HHH-12738 - Session/EntityManager is closed in ForeignGenerator (JTA setup)
This commit is contained in:
parent
c69038d476
commit
07738c4d89
|
@ -2107,7 +2107,7 @@ public final class SessionImpl
|
|||
|
||||
@Override
|
||||
public boolean contains(String entityName, Object object) {
|
||||
checkOpen();
|
||||
checkOpenOrWaitingForAutoClose();
|
||||
checkTransactionSynchStatus();
|
||||
|
||||
if ( object == null ) {
|
||||
|
|
|
@ -6,35 +6,12 @@
|
|||
*/
|
||||
package org.hibernate.test.idgen.foreign;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
|
|
|
@ -15,6 +15,8 @@ import javax.persistence.Column;
|
|||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
@ -36,15 +38,15 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-12738" )
|
||||
@TestForIssue(jiraKey = "HHH-12738")
|
||||
public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Contract.class,
|
||||
Customer.class,
|
||||
CustomerContractRelation.class
|
||||
Contract.class,
|
||||
Customer.class,
|
||||
CustomerContractRelation.class
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -128,12 +130,12 @@ public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunction
|
|||
entityManager.persist( customer );
|
||||
|
||||
customer = entityManager.createQuery(
|
||||
"SELECT c " +
|
||||
"FROM Customer c " +
|
||||
" LEFT JOIN FETCH c.contractRelations " +
|
||||
" WHERE c.id = :customerId", Customer.class )
|
||||
.setParameter( "customerId", customer.getId() )
|
||||
.getSingleResult();
|
||||
"SELECT c " +
|
||||
"FROM Customer c " +
|
||||
" LEFT JOIN FETCH c.contractRelations " +
|
||||
" WHERE c.id = :customerId", Customer.class )
|
||||
.setParameter( "customerId", customer.getId() )
|
||||
.getSingleResult();
|
||||
|
||||
CustomerContractRelation relation = new CustomerContractRelation();
|
||||
relation.setContractId( customer.getId() );
|
||||
|
@ -141,6 +143,62 @@ public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunction
|
|||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRelationImplicitFlushCloseEntityManager() throws Exception {
|
||||
|
||||
Long contractId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Contract contract = new Contract();
|
||||
|
||||
entityManager.persist( contract );
|
||||
return contract.getId();
|
||||
} );
|
||||
|
||||
Long customerId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Customer customer = new Customer();
|
||||
|
||||
entityManager.persist( customer );
|
||||
return customer.getId();
|
||||
} );
|
||||
|
||||
EntityManager entityManager = null;
|
||||
EntityTransaction txn = null;
|
||||
try {
|
||||
entityManager = entityManagerFactory().createEntityManager();
|
||||
txn = entityManager.getTransaction();
|
||||
txn.begin();
|
||||
|
||||
Customer customer = entityManager.createQuery(
|
||||
"SELECT c " +
|
||||
"FROM Customer c " +
|
||||
" LEFT JOIN FETCH c.contractRelations " +
|
||||
" WHERE c.id = :customerId", Customer.class )
|
||||
.setParameter( "customerId", customerId )
|
||||
.getSingleResult();
|
||||
|
||||
CustomerContractRelation relation = new CustomerContractRelation();
|
||||
relation.setContractId( contractId );
|
||||
customer.addContractRelation( relation );
|
||||
|
||||
//Close the EntityManager
|
||||
entityManager.close();
|
||||
|
||||
//And, afterward commit the currently running Tx.
|
||||
//This might happen in JTA environments where the Tx is committed by the JTA TM.
|
||||
txn.commit();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if ( txn != null && txn.isActive() ) {
|
||||
try {
|
||||
txn.rollback();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error( "Rollback failure", e );
|
||||
}
|
||||
}
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Contract")
|
||||
@Table(name = "CONTRACT")
|
||||
public static class Contract {
|
||||
|
@ -160,13 +218,12 @@ public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunction
|
|||
@Entity(name = "Customer")
|
||||
@Table(name = "CUSTOMER")
|
||||
public static class Customer {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE },
|
||||
orphanRemoval = true, targetEntity = CustomerContractRelation.class)
|
||||
private final Set<CustomerContractRelation> contractRelations = new HashSet<>();
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
|
Loading…
Reference in New Issue