HHH-18039 - EntityListeners defined in XML should replace those from annotations, not add to
This commit is contained in:
parent
fea7febff1
commit
41be577ffb
|
@ -854,11 +854,7 @@ public class ManagedTypeProcessor {
|
|||
xmlDocumentContext
|
||||
);
|
||||
|
||||
if ( jaxbEntity.getEntityListenerContainer() != null ) {
|
||||
jaxbEntity.getEntityListenerContainer().getEntityListeners().forEach( ( jaxbEntityListener -> {
|
||||
XmlAnnotationHelper.applyEntityListener( jaxbEntityListener, classDetails, xmlDocumentContext );
|
||||
} ) );
|
||||
}
|
||||
XmlAnnotationHelper.applyEntityListeners( jaxbEntity.getEntityListenerContainer(), classDetails, xmlDocumentContext );
|
||||
}
|
||||
|
||||
public static void processCompleteEmbeddable(
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorColumnImpl;
|
|||
import org.hibernate.boot.jaxb.mapping.spi.JaxbDiscriminatorFormulaImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerContainerImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListenerImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl;
|
||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbHbmFilterImpl;
|
||||
|
@ -1178,31 +1179,34 @@ public class XmlAnnotationHelper {
|
|||
idClassAnn.setAttributeValue( "value", idClassImpl );
|
||||
}
|
||||
|
||||
static void applyEntityListener(
|
||||
JaxbEntityListenerImpl jaxbEntityListener,
|
||||
public static void applyEntityListeners(
|
||||
JaxbEntityListenerContainerImpl entityListenerContainer,
|
||||
MutableClassDetails classDetails,
|
||||
XmlDocumentContext xmlDocumentContext) {
|
||||
final MutableAnnotationUsage<EntityListeners> listenersUsage = classDetails.applyAnnotationUsage(
|
||||
if ( entityListenerContainer == null || entityListenerContainer.getEntityListeners().isEmpty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MutableAnnotationUsage<EntityListeners> listenersUsage = classDetails.replaceAnnotationUsage(
|
||||
JpaAnnotations.ENTITY_LISTENERS,
|
||||
xmlDocumentContext.getModelBuildingContext()
|
||||
);
|
||||
final List<ClassDetails> values = arrayList( entityListenerContainer.getEntityListeners().size() );
|
||||
listenersUsage.setAttributeValue( "value", values );
|
||||
|
||||
final MutableClassDetails entityListenerClass = xmlDocumentContext.resolveJavaType( jaxbEntityListener.getClazz() );
|
||||
applyLifecycleCallbacks(
|
||||
jaxbEntityListener,
|
||||
JpaEventListenerStyle.LISTENER,
|
||||
entityListenerClass,
|
||||
xmlDocumentContext
|
||||
);
|
||||
final List<ClassDetails> values = listenersUsage.getAttributeValue( "value" );
|
||||
if ( values != null ) {
|
||||
entityListenerContainer.getEntityListeners().forEach( (jaxbEntityListener) -> {
|
||||
final MutableClassDetails entityListenerClass = xmlDocumentContext.resolveJavaType( jaxbEntityListener.getClazz() );
|
||||
applyLifecycleCallbacks(
|
||||
jaxbEntityListener,
|
||||
JpaEventListenerStyle.LISTENER,
|
||||
entityListenerClass,
|
||||
xmlDocumentContext
|
||||
);
|
||||
values.add( entityListenerClass );
|
||||
}
|
||||
else {
|
||||
listenersUsage.setAttributeValue( "value", new ArrayList<>( List.of( entityListenerClass ) ) );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void applyLifecycleCallbacks(
|
||||
JaxbLifecycleCallbackContainer lifecycleCallbackContainer,
|
||||
JpaEventListenerStyle callbackType,
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class CallbackTarget {
|
||||
private List<String> prePersistCallbacks = new ArrayList<>();
|
||||
private List<String> postPersistCallbacks = new ArrayList<>();
|
||||
|
||||
private List<String> preUpdateCallbacks = new ArrayList<>();
|
||||
private List<String> postUpdateCallbacks = new ArrayList<>();
|
||||
|
||||
private List<String> preRemoveCallbacks = new ArrayList<>();
|
||||
private List<String> postRemoveCallbacks = new ArrayList<>();
|
||||
|
||||
private List<String> postLoadCallbacks = new ArrayList<>();
|
||||
|
||||
public void prePersistCalled(String listenerName) {
|
||||
prePersistCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void postPersistCalled(String listenerName) {
|
||||
postPersistCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void preUpdateCalled(String listenerName) {
|
||||
preUpdateCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void postUpdateCalled(String listenerName) {
|
||||
postUpdateCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void preRemoveCalled(String listenerName) {
|
||||
preRemoveCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void postRemoveCalled(String listenerName) {
|
||||
postRemoveCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
public void postLoadCalled(String listenerName) {
|
||||
postLoadCallbacks.add( listenerName );
|
||||
}
|
||||
|
||||
|
||||
public List<String> getPrePersistCallbacks() {
|
||||
return prePersistCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPostPersistCallbacks() {
|
||||
return postPersistCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPreUpdateCallbacks() {
|
||||
return preUpdateCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPostUpdateCallbacks() {
|
||||
return postUpdateCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPreRemoveCallbacks() {
|
||||
return preRemoveCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPostRemoveCallbacks() {
|
||||
return postRemoveCallbacks;
|
||||
}
|
||||
|
||||
public List<String> getPostLoadCallbacks() {
|
||||
return postLoadCallbacks;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.ExcludeDefaultListeners;
|
||||
import jakarta.persistence.ExcludeSuperclassListeners;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@EntityListeners({ListenerC.class, ListenerB.class})
|
||||
@ExcludeDefaultListeners()
|
||||
@ExcludeSuperclassListeners
|
||||
public class LineItem extends LineItemSuper {
|
||||
@Id
|
||||
private Integer id;
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "order_fk")
|
||||
private Order order;
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "product_fk")
|
||||
private Product product;
|
||||
|
||||
public LineItem() {
|
||||
}
|
||||
|
||||
public LineItem(Integer id, Order order, Product product, int quantity) {
|
||||
super( quantity );
|
||||
this.id = id;
|
||||
this.order = order;
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Order getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(Order order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public Product getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public void setProduct(Product product) {
|
||||
this.product = product;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@EntityListeners({ListenerA.class, ListenerB.class})
|
||||
public class LineItemSuper extends CallbackTarget {
|
||||
private int quantity;
|
||||
|
||||
public LineItemSuper() {
|
||||
}
|
||||
|
||||
public LineItemSuper(int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerA {
|
||||
@PrePersist
|
||||
protected void prePersist(CallbackTarget target) {
|
||||
target.prePersistCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
protected void postPersist(CallbackTarget target) {
|
||||
target.postPersistCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
protected void preRemove(CallbackTarget target) {
|
||||
target.preRemoveCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
protected void postRemove(CallbackTarget target) {
|
||||
target.postRemoveCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void preUpdate(CallbackTarget target) {
|
||||
target.preUpdateCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
protected void postUpdate(CallbackTarget target) {
|
||||
target.postUpdateCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
protected void postLoad(CallbackTarget target) {
|
||||
target.postLoadCalled( "ListenerA" );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerB {
|
||||
@PrePersist
|
||||
protected void prePersist(CallbackTarget target) {
|
||||
target.prePersistCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
protected void postPersist(CallbackTarget target) {
|
||||
target.postPersistCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
protected void preRemove(CallbackTarget target) {
|
||||
target.preRemoveCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
protected void postRemove(CallbackTarget target) {
|
||||
target.postRemoveCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void preUpdate(CallbackTarget target) {
|
||||
target.preUpdateCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
protected void postUpdate(CallbackTarget target) {
|
||||
target.postUpdateCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
protected void postLoad(CallbackTarget target) {
|
||||
target.postLoadCalled( "ListenerB" );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class ListenerBase {
|
||||
protected abstract String getListenerName();
|
||||
|
||||
@PrePersist
|
||||
protected void prePersist(CallbackTarget target) {
|
||||
target.prePersistCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
protected void postPersist(CallbackTarget target) {
|
||||
target.postPersistCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
protected void preRemove(CallbackTarget target) {
|
||||
target.preRemoveCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
protected void postRemove(CallbackTarget target) {
|
||||
target.postRemoveCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void preUpdate(CallbackTarget target) {
|
||||
target.preUpdateCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
protected void postUpdate(CallbackTarget target) {
|
||||
target.postUpdateCalled( getListenerName() );
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
protected void postLoad(CallbackTarget target) {
|
||||
target.postLoadCalled( getListenerName() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PostRemove;
|
||||
import jakarta.persistence.PostUpdate;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreRemove;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ListenerC {
|
||||
|
||||
@PrePersist
|
||||
protected void prePersist(CallbackTarget target) {
|
||||
target.prePersistCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
protected void postPersist(CallbackTarget target) {
|
||||
target.postPersistCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
protected void preRemove(CallbackTarget target) {
|
||||
target.preRemoveCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PostRemove
|
||||
protected void postRemove(CallbackTarget target) {
|
||||
target.postRemoveCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
protected void preUpdate(CallbackTarget target) {
|
||||
target.preUpdateCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PostUpdate
|
||||
protected void postUpdate(CallbackTarget target) {
|
||||
target.postUpdateCalled( "ListenerC" );
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
protected void postLoad(CallbackTarget target) {
|
||||
target.postLoadCalled( "ListenerC" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "orders")
|
||||
@EntityListeners({ListenerC.class, ListenerB.class})
|
||||
public class Order extends CallbackTarget {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Column(name = "total_price")
|
||||
private double totalPrice;
|
||||
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
|
||||
private Collection<LineItem> lineItems = new java.util.ArrayList<>();
|
||||
|
||||
public Order() {
|
||||
}
|
||||
|
||||
public Order(Integer id, double totalPrice) {
|
||||
this.id = id;
|
||||
this.totalPrice = totalPrice;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public double getTotalPrice() {
|
||||
return totalPrice;
|
||||
}
|
||||
|
||||
public void setTotalPrice(double totalPrice) {
|
||||
this.totalPrice = totalPrice;
|
||||
}
|
||||
|
||||
public Collection<LineItem> getLineItems() {
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
public void setLineItems(Collection<LineItem> lineItems) {
|
||||
this.lineItems = lineItems;
|
||||
}
|
||||
|
||||
public void addLineItem(LineItem lineItem) {
|
||||
if ( lineItems == null ) {
|
||||
lineItems = new ArrayList<>();
|
||||
}
|
||||
lineItems.add( lineItem );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||
@DomainModel(
|
||||
annotatedClasses = {Product.class,Order.class, LineItemSuper.class, LineItem.class},
|
||||
xmlMappings = "mappings/callbacks/listener_overrides.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class OverridesTests {
|
||||
public static final String[] LISTENER_ABC = {"ListenerA", "ListenerB", "ListenerC"};
|
||||
public static final String[] LISTENER_BC = {"ListenerB", "ListenerC"};
|
||||
|
||||
@Test
|
||||
void testSimplePersist(SessionFactoryScope scope) {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
scope.inTransaction( (session) -> {
|
||||
session.persist( product );
|
||||
assertThat( product.getPrePersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
} );
|
||||
assertThat( product.getPostPersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCascadingPersist(SessionFactoryScope scope) {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
final Order order = new Order( 1, 246 );
|
||||
final LineItem lineItem = new LineItem( 1, order, product, 2 );
|
||||
order.addLineItem( lineItem );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
session.persist( product );
|
||||
session.persist( order );
|
||||
|
||||
assertThat( product.getPrePersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( order.getPrePersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( lineItem.getPrePersistCallbacks() ).containsExactly( LISTENER_BC );
|
||||
} );
|
||||
|
||||
assertThat( product.getPostPersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( order.getPostPersistCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( lineItem.getPostPersistCallbacks() ).containsExactly( LISTENER_BC );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleRemove(SessionFactoryScope scope) {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
scope.inTransaction( (session) -> {
|
||||
session.persist( product );
|
||||
} );
|
||||
scope.inTransaction( (session) -> {
|
||||
session.remove( product );
|
||||
assertThat( product.getPreRemoveCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
} );
|
||||
assertThat( product.getPostRemoveCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCascadingRemove(SessionFactoryScope scope) {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
final Order order = new Order( 1, 246 );
|
||||
final LineItem lineItem = new LineItem( 1, order, product, 2 );
|
||||
order.addLineItem( lineItem );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
session.persist( product );
|
||||
session.persist( order );
|
||||
} );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
session.remove( order );
|
||||
assertThat( order.getPreRemoveCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( lineItem.getPreRemoveCallbacks() ).containsExactly( LISTENER_BC );
|
||||
} );
|
||||
|
||||
assertThat( order.getPostRemoveCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( lineItem.getPostRemoveCallbacks() ).containsExactly( LISTENER_BC );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSimpleUpdate(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
session.persist( product );
|
||||
} );
|
||||
|
||||
|
||||
final Product updated = scope.fromTransaction( (session) -> {
|
||||
final Product product = session.find( Product.class, 1 );
|
||||
|
||||
assertThat( product.getPreUpdateCallbacks() ).isEmpty();
|
||||
assertThat( product.getPostUpdateCallbacks() ).isEmpty();
|
||||
|
||||
product.setCost( 789 );
|
||||
|
||||
return product;
|
||||
} );
|
||||
|
||||
assertThat( updated.getPreUpdateCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
assertThat( updated.getPostUpdateCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoading(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
final Product product = new Product( 1, "987654321", 123 );
|
||||
final Order order = new Order( 1, 246 );
|
||||
final LineItem lineItem = new LineItem( 1, order, product, 2 );
|
||||
order.addLineItem( lineItem );
|
||||
|
||||
session.persist( product );
|
||||
session.persist( order );
|
||||
} );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
final Product product = session.find( Product.class, 1 );
|
||||
assertThat( product.getPostLoadCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
} );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
final List<Product> products = session.createSelectionQuery( "from Product", Product.class ).list();
|
||||
products.forEach( (product) -> {
|
||||
assertThat( product.getPostLoadCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
} );
|
||||
} );
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
final LineItem lineItem = session.find( LineItem.class, 1 );
|
||||
assertThat( lineItem.getPostLoadCallbacks() ).containsExactly( LISTENER_BC );
|
||||
assertThat( lineItem.getOrder().getPostLoadCallbacks() ).containsExactly( LISTENER_ABC );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void dropData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( (session) -> {
|
||||
session.createMutationQuery( "delete LineItem" ).executeUpdate();
|
||||
session.createMutationQuery( "delete Order" ).executeUpdate();
|
||||
session.createMutationQuery( "delete Product" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@EntityListeners({ListenerC.class, ListenerB.class})
|
||||
public class Product extends CallbackTarget {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String partNumber;
|
||||
private double cost;
|
||||
|
||||
public Product() {
|
||||
}
|
||||
|
||||
public Product(Integer id, String partNumber, double cost) {
|
||||
this.id = id;
|
||||
this.partNumber = partNumber;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getPartNumber() {
|
||||
return partNumber;
|
||||
}
|
||||
|
||||
public void setPartNumber(String partNumber) {
|
||||
this.partNumber = partNumber;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCost(double cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
~ See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
-->
|
||||
<entity-mappings xmlns="https://jakarta.ee/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm/orm_3_2.xsd"
|
||||
version="3.2">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
<entity-listener class="org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides.ListenerA">
|
||||
</entity-listener>
|
||||
</entity-listeners>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
|
||||
<package>org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides</package>
|
||||
|
||||
<entity class="Product">
|
||||
<entity-listeners>
|
||||
<entity-listener class="ListenerB"/>
|
||||
<entity-listener class="org.hibernate.orm.test.jpa.compliance.callback.listeneroverrides.ListenerC"/>
|
||||
</entity-listeners>
|
||||
</entity>
|
||||
|
||||
<entity class="Order">
|
||||
<entity-listeners>
|
||||
<entity-listener class="ListenerB"/>
|
||||
<entity-listener class="ListenerC"/>
|
||||
</entity-listeners>
|
||||
</entity>
|
||||
|
||||
<entity class="LineItem">
|
||||
<entity-listeners>
|
||||
<entity-listener class="ListenerB"/>
|
||||
<entity-listener class="ListenerC"/>
|
||||
</entity-listeners>
|
||||
</entity>
|
||||
|
||||
</entity-mappings>
|
Loading…
Reference in New Issue