|
4 | 4 | */ |
5 | 5 | package org.hibernate.search.integrationtest.mapper.orm.automaticindexing.association.bytype.onetoone.ownedbycontaining; |
6 | 6 |
|
| 7 | +import static org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmUtils.with; |
| 8 | + |
7 | 9 | import java.util.ArrayList; |
8 | 10 | import java.util.List; |
9 | 11 | import java.util.Optional; |
10 | 12 | import java.util.stream.Stream; |
11 | 13 |
|
12 | 14 | import jakarta.persistence.Basic; |
| 15 | +import jakarta.persistence.CascadeType; |
13 | 16 | import jakarta.persistence.CollectionTable; |
14 | 17 | import jakarta.persistence.Column; |
15 | 18 | import jakarta.persistence.ElementCollection; |
|
18 | 21 | import jakarta.persistence.Id; |
19 | 22 | import jakarta.persistence.JoinColumn; |
20 | 23 | import jakarta.persistence.ManyToOne; |
| 24 | +import jakarta.persistence.MapsId; |
21 | 25 | import jakarta.persistence.OneToOne; |
22 | 26 | import jakarta.persistence.OrderColumn; |
23 | 27 | import jakarta.persistence.Transient; |
|
29 | 33 | import org.hibernate.search.integrationtest.mapper.orm.automaticindexing.association.bytype.accessor.PropertyAccessor; |
30 | 34 | import org.hibernate.search.mapper.pojo.automaticindexing.ReindexOnUpdate; |
31 | 35 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.AssociationInverseSide; |
| 36 | +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.DocumentId; |
32 | 37 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; |
33 | 38 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; |
34 | 39 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded; |
|
37 | 42 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.PropertyValue; |
38 | 43 | import org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmSetupHelper; |
39 | 44 |
|
| 45 | +import org.junit.jupiter.api.Test; |
| 46 | + |
40 | 47 | /** |
41 | 48 | * Test automatic indexing caused by single-valued association updates |
42 | 49 | * or by updates of associated (contained) entities, |
@@ -78,9 +85,47 @@ protected OrmSetupHelper.SetupContext additionalSetup(OrmSetupHelper.SetupContex |
78 | 85 | // See https://hibernate.zulipchat.com/#narrow/stream/132094-hibernate-orm-dev/topic/lazy.20associations.20with.20ORM.206 |
79 | 86 | setupContext.withProperty( AvailableSettings.MAX_FETCH_DEPTH, 1 ); |
80 | 87 |
|
| 88 | + setupContext.withAnnotatedTypes( CascadingParent.class, CascadableChildMapsId.class ); |
| 89 | + setupContext.dataClearing( config -> config.manualDatabaseCleanup( session -> { |
| 90 | + session.getSessionFactory().getSchemaManager().truncateMappedObjects(); |
| 91 | + } ) ); |
| 92 | + backendMock.expectAnySchema( CascadableChildMapsId.INDEX ); |
| 93 | + |
81 | 94 | return setupContext; |
82 | 95 | } |
83 | 96 |
|
| 97 | + @Test |
| 98 | + void deleteWithCascade() { |
| 99 | + with( sessionFactory ).runInTransaction( session -> { |
| 100 | + CascadingParent p = new CascadingParent( 1L, "Parent" ); |
| 101 | + CascadableChildMapsId entity = new CascadableChildMapsId( p, "Entity" ); |
| 102 | + |
| 103 | + session.persist( p ); |
| 104 | + session.persist( entity ); |
| 105 | + |
| 106 | + backendMock.expectWorks( CascadableChildMapsId.INDEX ) |
| 107 | + .add( "1", b -> b |
| 108 | + .field( "name", "Entity" ) |
| 109 | + .objectField( "parent", b2 -> b2 |
| 110 | + .field( "parentName", "Parent" ) ) |
| 111 | + ); |
| 112 | + } ); |
| 113 | + backendMock.verifyExpectationsMet(); |
| 114 | + |
| 115 | + with( sessionFactory ).runInTransaction( session -> { |
| 116 | + CascadingParent parent = session.find( CascadingParent.class, 1L ); |
| 117 | + |
| 118 | + CascadableChildMapsId child = session.find( CascadableChildMapsId.class, 1L ); |
| 119 | + child.setName( "to-be-deleted" ); |
| 120 | + session.persist( child ); |
| 121 | + session.remove( parent ); |
| 122 | + |
| 123 | + backendMock.expectWorks( CascadableChildMapsId.INDEX ) |
| 124 | + .delete( "1" ); |
| 125 | + } ); |
| 126 | + backendMock.verifyExpectationsMet(); |
| 127 | + } |
| 128 | + |
84 | 129 | @Entity(name = "containing") |
85 | 130 | public static class ContainingEntity { |
86 | 131 |
|
@@ -848,4 +893,101 @@ public PropertyAccessor<ContainedEmbeddable, ContainingEntity> containingAsNonIn |
848 | 893 | }; |
849 | 894 | } |
850 | 895 |
|
| 896 | + @Entity(name = "CascadingParent") |
| 897 | + public static class CascadingParent { |
| 898 | + |
| 899 | + @Id |
| 900 | + private Long id; |
| 901 | + |
| 902 | + @GenericField |
| 903 | + private String parentName; |
| 904 | + |
| 905 | + @OneToOne(mappedBy = "parent", cascade = CascadeType.ALL) |
| 906 | + private CascadableChildMapsId cascadableChildMapsId; |
| 907 | + |
| 908 | + public CascadingParent() { |
| 909 | + } |
| 910 | + |
| 911 | + public CascadingParent(Long id, String parentName) { |
| 912 | + this.id = id; |
| 913 | + this.parentName = parentName; |
| 914 | + } |
| 915 | + |
| 916 | + public Long getId() { |
| 917 | + return id; |
| 918 | + } |
| 919 | + |
| 920 | + public void setId(Long id) { |
| 921 | + this.id = id; |
| 922 | + } |
| 923 | + |
| 924 | + public String getParentName() { |
| 925 | + return parentName; |
| 926 | + } |
| 927 | + |
| 928 | + public void setParentName(String parentName) { |
| 929 | + this.parentName = parentName; |
| 930 | + } |
| 931 | + |
| 932 | + public CascadableChildMapsId getMapsIdJoinColumnChild() { |
| 933 | + return cascadableChildMapsId; |
| 934 | + } |
| 935 | + |
| 936 | + public void setMapsIdJoinColumnChild(CascadableChildMapsId cascadableChildMapsId) { |
| 937 | + this.cascadableChildMapsId = cascadableChildMapsId; |
| 938 | + } |
| 939 | + |
| 940 | + } |
| 941 | + |
| 942 | + @Entity(name = "CascadableChildMapsId") |
| 943 | + @Indexed(index = CascadableChildMapsId.INDEX) |
| 944 | + public static class CascadableChildMapsId { |
| 945 | + static final String INDEX = "CascadableChildMapsId"; |
| 946 | + |
| 947 | + @Id |
| 948 | + @DocumentId |
| 949 | + private Long id; |
| 950 | + |
| 951 | + @MapsId |
| 952 | + @JoinColumn(name = "PARENT_ID_CUSTOM_NAME") |
| 953 | + @OneToOne |
| 954 | + @IndexedEmbedded |
| 955 | + @AssociationInverseSide(inversePath = @ObjectPath(@PropertyValue(propertyName = "cascadableChildMapsId"))) |
| 956 | + private CascadingParent parent; |
| 957 | + |
| 958 | + @GenericField |
| 959 | + @Column(name = "NAME") |
| 960 | + private String name; |
| 961 | + |
| 962 | + protected CascadableChildMapsId() { |
| 963 | + } |
| 964 | + |
| 965 | + public CascadableChildMapsId(Long id, String name) { |
| 966 | + this.id = id; |
| 967 | + this.name = name; |
| 968 | + } |
| 969 | + |
| 970 | + public CascadableChildMapsId(CascadingParent parent, String name) { |
| 971 | + this.id = parent.getId(); |
| 972 | + this.parent = parent; |
| 973 | + this.name = name; |
| 974 | + } |
| 975 | + |
| 976 | + public Long getId() { |
| 977 | + return id; |
| 978 | + } |
| 979 | + |
| 980 | + public CascadingParent getParent() { |
| 981 | + return parent; |
| 982 | + } |
| 983 | + |
| 984 | + public String getName() { |
| 985 | + return name; |
| 986 | + } |
| 987 | + |
| 988 | + public void setName(String name) { |
| 989 | + this.name = name; |
| 990 | + } |
| 991 | + } |
| 992 | + |
851 | 993 | } |
0 commit comments