Fix postLoad callback method not called
This commit is contained in:
parent
8d43be4b78
commit
b8114bad31
|
@ -425,6 +425,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
|| entityDescriptor.getJavaTypeDescriptor().getJavaTypeClass().isInstance( proxy ) ) ) {
|
||||
if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) {
|
||||
this.entityInstance = entityInstanceFromExecutionContext;
|
||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||
}
|
||||
else {
|
||||
this.entityInstance = proxy;
|
||||
|
@ -435,9 +436,11 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
|
||||
if ( existingEntity != null ) {
|
||||
this.entityInstance = existingEntity;
|
||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||
}
|
||||
else if ( this instanceof EntityResultInitializer && entityInstanceFromExecutionContext != null ) {
|
||||
this.entityInstance = entityInstanceFromExecutionContext;
|
||||
registerLoadingEntity( rowProcessingState, entityInstance );
|
||||
}
|
||||
else {
|
||||
// look to see if another initializer from a parent load context or an earlier
|
||||
|
@ -578,6 +581,12 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
}
|
||||
}
|
||||
|
||||
registerLoadingEntity( rowProcessingState, instance );
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void registerLoadingEntity(RowProcessingState rowProcessingState, Object instance) {
|
||||
final LoadingEntityEntry loadingEntry = new LoadingEntityEntry(
|
||||
this,
|
||||
entityKey,
|
||||
|
@ -588,8 +597,6 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
entityKey,
|
||||
loadingEntry
|
||||
);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -625,6 +632,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
}
|
||||
|
||||
notifyResolutionListeners( entityInstanceForNotify );
|
||||
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import org.hibernate.event.spi.EventSource;
|
|||
import org.hibernate.event.spi.PostLoadEvent;
|
||||
import org.hibernate.event.spi.PostLoadEventListener;
|
||||
import org.hibernate.event.spi.PreLoadEvent;
|
||||
import org.hibernate.mapping.UniqueKey;
|
||||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.sql.exec.spi.Callback;
|
||||
import org.hibernate.sql.results.graph.Initializer;
|
||||
|
|
|
@ -28,9 +28,9 @@ public class PostLoadTest {
|
|||
*/
|
||||
@Test
|
||||
public void testAccessAssociatedSetInPostLoad(EntityManagerFactoryScope scope) {
|
||||
scope.inEntityManager(
|
||||
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
try {
|
||||
Child child = new Child();
|
||||
child.setId( 1 );
|
||||
Parent daddy = new Parent();
|
||||
|
@ -40,21 +40,15 @@ public class PostLoadTest {
|
|||
children.add( child );
|
||||
daddy.setChildren( children );
|
||||
|
||||
entityManager.getTransaction().begin();
|
||||
entityManager.persist( daddy );
|
||||
entityManager.getTransaction().commit();
|
||||
entityManager.clear();
|
||||
}
|
||||
);
|
||||
|
||||
daddy = entityManager.find( Parent.class, 1 );
|
||||
scope.inEntityManager(
|
||||
entityManager -> {
|
||||
Parent daddy = entityManager.find( Parent.class, 1 );
|
||||
assertEquals( 1, daddy.getNrOfChildren() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( entityManager.getTransaction().isActive() ) {
|
||||
entityManager.getTransaction().rollback();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.DiscriminatorColumn;
|
||||
import jakarta.persistence.DiscriminatorType;
|
||||
import jakarta.persistence.DiscriminatorValue;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import jakarta.persistence.PostLoad;
|
||||
import jakarta.persistence.PostPersist;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.Query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@Jpa(
|
||||
annotatedClasses = {
|
||||
PostLoadCallbackTest.Account.class,
|
||||
PostLoadCallbackTest.DebitAccount.class,
|
||||
PostLoadCallbackTest.CreditAccount.class,
|
||||
PostLoadCallbackTest.Person.class
|
||||
}
|
||||
)
|
||||
public class PostLoadCallbackTest {
|
||||
|
||||
@Test
|
||||
public void testEntityListenerPostLoadMethodIsCalled(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
CreditAccount account = new CreditAccount(
|
||||
1,
|
||||
"drea",
|
||||
BigDecimal.valueOf( 190 ),
|
||||
BigDecimal.valueOf( 10000 )
|
||||
);
|
||||
|
||||
entityManager.persist( account );
|
||||
entityManager.flush();
|
||||
entityManager.refresh( account );
|
||||
|
||||
Query query = entityManager.createQuery( "select ca from CreditAccount ca" );
|
||||
query.getResultList();
|
||||
|
||||
if ( !account.isPostLoadCalled() ) {
|
||||
fail( "PostLoad has not been called" );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostLoadMethodIsCalled(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
Person person = new Person( 1, "Fab" );
|
||||
entityManager.persist( person );
|
||||
entityManager.flush();
|
||||
entityManager.refresh( person );
|
||||
|
||||
Query query = entityManager
|
||||
.createQuery( "select p from Person p" );
|
||||
query.getResultList();
|
||||
if ( person.isPostLoadCalled() ) {
|
||||
fail( "PostLoad has not been called" );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@MappedSuperclass
|
||||
public static class PersonCallback {
|
||||
|
||||
boolean isPrePersistCalled;
|
||||
boolean isPostPersistCalled;
|
||||
|
||||
@PrePersist
|
||||
public void prePersist() {
|
||||
isPrePersistCalled = true;
|
||||
}
|
||||
|
||||
@PostPersist
|
||||
public void postPersist() {
|
||||
if ( !isPrePersistCalled ) {
|
||||
throw new IllegalStateException(
|
||||
"The prePersist method has not been called." );
|
||||
}
|
||||
this.isPostPersistCalled = true;
|
||||
}
|
||||
|
||||
public boolean isPostLoadCalled() {
|
||||
return isPostPersistCalled;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Person")
|
||||
public static class Person extends PersonCallback {
|
||||
|
||||
Person() {
|
||||
}
|
||||
|
||||
public Person(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
}
|
||||
|
||||
@Entity(name = "Account")
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
@DiscriminatorColumn(name = "ACCOUNT_TYPE", discriminatorType = DiscriminatorType.STRING)
|
||||
@DiscriminatorValue("Account")
|
||||
@EntityListeners(AccountListener.class)
|
||||
public static class Account extends CallbackStatus {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private String owner;
|
||||
|
||||
private BigDecimal balance;
|
||||
|
||||
public Account() {
|
||||
}
|
||||
|
||||
public Account(Integer id, String owner, BigDecimal balance) {
|
||||
this.id = id;
|
||||
this.owner = owner;
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "DebitAccount")
|
||||
@DiscriminatorValue("DebitAccount")
|
||||
@EntityListeners(AccountListener.class)
|
||||
public static class DebitAccount extends Account {
|
||||
private BigDecimal overdraftFee;
|
||||
|
||||
public DebitAccount(Integer id, String owner, BigDecimal balance, BigDecimal overdraftFee) {
|
||||
super( id, owner, balance );
|
||||
this.overdraftFee = overdraftFee;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "CreditAccount")
|
||||
@DiscriminatorValue("CreditAccount")
|
||||
@EntityListeners(AccountListener.class)
|
||||
public static class CreditAccount extends Account {
|
||||
private BigDecimal creditLimit;
|
||||
|
||||
public CreditAccount(Integer id, String owner, BigDecimal balance, BigDecimal creditLimit) {
|
||||
super( id, owner, balance );
|
||||
this.creditLimit = creditLimit;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccountListener {
|
||||
|
||||
@PostPersist
|
||||
public void postPersist(CallbackStatus callbackStatus) {
|
||||
callbackStatus.setPostPersistCall();
|
||||
}
|
||||
|
||||
@PostLoad
|
||||
public void postLoad(CallbackStatus callbackStatus) {
|
||||
callbackStatus.setPostLoadCalled();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class CallbackStatus {
|
||||
|
||||
private boolean postPersistCalled;
|
||||
|
||||
private boolean postLoadCalled;
|
||||
|
||||
public boolean isPostLoadCalled() {
|
||||
return postLoadCalled;
|
||||
}
|
||||
|
||||
public void setPostLoadCalled() {
|
||||
postLoadCalled = true;
|
||||
}
|
||||
|
||||
public void setPostPersistCall() {
|
||||
postPersistCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue