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
|
@Override
|
||||||
public boolean contains(String entityName, Object object) {
|
public boolean contains(String entityName, Object object) {
|
||||||
checkOpen();
|
checkOpenOrWaitingForAutoClose();
|
||||||
checkTransactionSynchStatus();
|
checkTransactionSynchStatus();
|
||||||
|
|
||||||
if ( object == null ) {
|
if ( object == null ) {
|
||||||
|
|
|
@ -6,35 +6,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.idgen.foreign;
|
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.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.cfg.Environment;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
import org.hibernate.testing.jta.TestingJtaBootstrap;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
|
|
@ -15,6 +15,8 @@ import javax.persistence.Column;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.EmbeddedId;
|
import javax.persistence.EmbeddedId;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
import javax.persistence.FetchType;
|
import javax.persistence.FetchType;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
@ -36,15 +38,15 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@TestForIssue( jiraKey = "HHH-12738" )
|
@TestForIssue(jiraKey = "HHH-12738")
|
||||||
public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunctionalTestCase {
|
public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] {
|
return new Class[] {
|
||||||
Contract.class,
|
Contract.class,
|
||||||
Customer.class,
|
Customer.class,
|
||||||
CustomerContractRelation.class
|
CustomerContractRelation.class
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +130,12 @@ public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunction
|
||||||
entityManager.persist( customer );
|
entityManager.persist( customer );
|
||||||
|
|
||||||
customer = entityManager.createQuery(
|
customer = entityManager.createQuery(
|
||||||
"SELECT c " +
|
"SELECT c " +
|
||||||
"FROM Customer c " +
|
"FROM Customer c " +
|
||||||
" LEFT JOIN FETCH c.contractRelations " +
|
" LEFT JOIN FETCH c.contractRelations " +
|
||||||
" WHERE c.id = :customerId", Customer.class )
|
" WHERE c.id = :customerId", Customer.class )
|
||||||
.setParameter( "customerId", customer.getId() )
|
.setParameter( "customerId", customer.getId() )
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
|
|
||||||
CustomerContractRelation relation = new CustomerContractRelation();
|
CustomerContractRelation relation = new CustomerContractRelation();
|
||||||
relation.setContractId( customer.getId() );
|
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")
|
@Entity(name = "Contract")
|
||||||
@Table(name = "CONTRACT")
|
@Table(name = "CONTRACT")
|
||||||
public static class Contract {
|
public static class Contract {
|
||||||
|
@ -160,13 +218,12 @@ public class ForeignGeneratorResourceLocalTest extends BaseEntityManagerFunction
|
||||||
@Entity(name = "Customer")
|
@Entity(name = "Customer")
|
||||||
@Table(name = "CUSTOMER")
|
@Table(name = "CUSTOMER")
|
||||||
public static class Customer {
|
public static class Customer {
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE },
|
@OneToMany(mappedBy = "customer", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE },
|
||||||
orphanRemoval = true, targetEntity = CustomerContractRelation.class)
|
orphanRemoval = true, targetEntity = CustomerContractRelation.class)
|
||||||
private final Set<CustomerContractRelation> contractRelations = new HashSet<>();
|
private final Set<CustomerContractRelation> contractRelations = new HashSet<>();
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
Loading…
Reference in New Issue