revert back changes in 'org.hibernate.test.cascade'
This commit is contained in:
parent
30bfe89246
commit
db50e046e2
|
@ -14,34 +14,42 @@ public enum CascadeType {
|
|||
* Includes all types listed here.
|
||||
*/
|
||||
ALL,
|
||||
|
||||
/**
|
||||
* Corresponds to {@link javax.persistence.CascadeType#PERSIST}.
|
||||
*/
|
||||
PERSIST,
|
||||
|
||||
/**
|
||||
* Corresponds to {@link javax.persistence.CascadeType#MERGE}.
|
||||
*/
|
||||
MERGE,
|
||||
|
||||
/**
|
||||
* Corresponds to {@link javax.persistence.CascadeType#REMOVE}.
|
||||
*/
|
||||
REMOVE,
|
||||
|
||||
/**
|
||||
* Corresponds to {@link javax.persistence.CascadeType#REFRESH}.
|
||||
*/
|
||||
REFRESH,
|
||||
|
||||
/**
|
||||
* Corresponds to the Hibernate native DELETE action.
|
||||
*/
|
||||
DELETE,
|
||||
|
||||
/**
|
||||
* Corresponds to the Hibernate native SAVE_UPDATE (direct reattachment) action.
|
||||
*/
|
||||
SAVE_UPDATE,
|
||||
|
||||
/**
|
||||
* Corresponds to the Hibernate native REPLICATE action.
|
||||
*/
|
||||
REPLICATE,
|
||||
|
||||
/**
|
||||
* Hibernate originally handled orphan removal as a specialized cascade.
|
||||
*
|
||||
|
@ -49,10 +57,12 @@ public enum CascadeType {
|
|||
*/
|
||||
@Deprecated
|
||||
DELETE_ORPHAN,
|
||||
|
||||
/**
|
||||
* Corresponds to the Hibernate native LOCK action.
|
||||
*/
|
||||
LOCK,
|
||||
|
||||
/**
|
||||
* JPA originally planned on calling DETACH EVICT.
|
||||
*
|
||||
|
@ -60,6 +70,7 @@ public enum CascadeType {
|
|||
*/
|
||||
@Deprecated
|
||||
EVICT,
|
||||
|
||||
/**
|
||||
* Corresponds to {@link javax.persistence.CascadeType#DETACH}.
|
||||
*/
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -63,11 +62,7 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
|
|||
|
||||
final int numberOfIds = ArrayHelper.countNonNull( batchIds );
|
||||
if ( numberOfIds <= 1 ) {
|
||||
if ( singleIdLoader == null ) {
|
||||
singleIdLoader = new SingleIdEntityLoaderStandardImpl<>( getLoadable(), session.getFactory() );
|
||||
singleIdLoader.prepare();
|
||||
}
|
||||
|
||||
initializeSingleIdLoaderIfNeeded( session );
|
||||
|
||||
final T result = singleIdLoader.load( pkValue, lockOptions, session );
|
||||
if ( result == null ) {
|
||||
|
@ -187,6 +182,14 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
|
|||
Object entityInstance,
|
||||
LockOptions lockOptions,
|
||||
SharedSessionContractImplementor session) {
|
||||
initializeSingleIdLoaderIfNeeded( session );
|
||||
return singleIdLoader.load( pkValue, entityInstance, lockOptions, session );
|
||||
}
|
||||
|
||||
private void initializeSingleIdLoaderIfNeeded(SharedSessionContractImplementor session) {
|
||||
if ( singleIdLoader == null ) {
|
||||
singleIdLoader = new SingleIdEntityLoaderStandardImpl<>( getLoadable(), session.getFactory() );
|
||||
singleIdLoader.prepare();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,6 +136,11 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
|
|||
return entityInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityId() {
|
||||
return restrictedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryOptions getQueryOptions() {
|
||||
return QueryOptions.NONE;
|
||||
|
|
|
@ -23,7 +23,8 @@ public interface SingleIdEntityLoader<T> extends SingleEntityLoader<T> {
|
|||
|
||||
/**
|
||||
* Load by primary key value, populating the passed entity instance. Used to initialize an uninitialized
|
||||
* bytecode-proxy. The passed instance is the enhanced proxy
|
||||
* bytecode-proxy or {@link org.hibernate.event.spi.LoadEvent} handling.
|
||||
* The passed instance is the enhanced proxy or the entity to be loaded.
|
||||
*/
|
||||
T load(Object pkValue, Object entityInstance, LockOptions lockOptions, SharedSessionContractImplementor session);
|
||||
|
||||
|
|
|
@ -4470,7 +4470,12 @@ public abstract class AbstractEntityPersister
|
|||
LOG.tracev( "Fetching entity: {0}", MessageHelper.infoString( this, id, getFactory() ) );
|
||||
}
|
||||
|
||||
return singleIdEntityLoader.load( id, lockOptions, session );
|
||||
if ( optionalObject == null ) {
|
||||
return singleIdEntityLoader.load( id, lockOptions, session );
|
||||
}
|
||||
else {
|
||||
return singleIdEntityLoader.load( id, optionalObject, lockOptions, session );
|
||||
}
|
||||
}
|
||||
|
||||
public SingleIdEntityLoader getSingleIdEntityLoader() {
|
||||
|
|
|
@ -158,7 +158,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
|
|||
|
||||
@Override
|
||||
public Object getEffectiveOptionalId() {
|
||||
return null;
|
||||
return executionContext.getEntityId();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,6 +45,10 @@ public interface ExecutionContext {
|
|||
return null;
|
||||
}
|
||||
|
||||
default Object getEntityId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default void registerLoadingEntityEntry(EntityKey entityKey, LoadingEntityEntry entry) {
|
||||
// by default do nothing
|
||||
}
|
||||
|
|
|
@ -398,8 +398,9 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
// this isEntityReturn bit is just for entity loaders, not hql/criteria
|
||||
if ( isEntityReturn() ) {
|
||||
final Object requestedEntityId = rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions().getEffectiveOptionalId();
|
||||
if ( requestedEntityId != null && requestedEntityId.equals( entityKey.getIdentifier() ) ) {
|
||||
entityInstance = rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions().getEffectiveOptionalObject();
|
||||
final Object optionalEntityInstance = rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions().getEffectiveOptionalObject();
|
||||
if ( requestedEntityId != null && optionalEntityInstance != null && requestedEntityId.equals( entityKey.getIdentifier() ) ) {
|
||||
entityInstance = optionalEntityInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,20 +6,30 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.cascade;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Statement;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Implementation of RefreshTest.
|
||||
|
@ -27,61 +37,113 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = {
|
||||
"org/hibernate/orm/test/cascade/Job.hbm.xml",
|
||||
"org/hibernate/orm/test/cascade/JobBatch.hbm.xml"
|
||||
}
|
||||
annotatedClasses = {
|
||||
RefreshTest.Job.class,
|
||||
RefreshTest.JobBatch.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@FailureExpected( reason = "This should be fixed by Nathan PR")
|
||||
public class RefreshTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshCascade(SessionFactoryScope scope) {
|
||||
private JobBatch batch;
|
||||
|
||||
@BeforeEach
|
||||
void setUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
JobBatch batch = new JobBatch( new Date() );
|
||||
batch.createJob().setProcessingInstructions( "Just do it!" );
|
||||
batch.createJob().setProcessingInstructions( "I know you can do it!" );
|
||||
session -> {
|
||||
batch = new JobBatch( new Date() );
|
||||
batch.createJob().processingInstructions = "Just do it!";
|
||||
batch.createJob().processingInstructions = "I know you can do it!";
|
||||
|
||||
// write the stuff to the database; at this stage all job.status values are zero
|
||||
session.persist( batch );
|
||||
session.flush();
|
||||
// write the stuff to the database; at this stage all job.status values are zero
|
||||
session.save( batch );
|
||||
}
|
||||
);
|
||||
|
||||
// behind the session's back, let's modify the statuses
|
||||
updateStatuses( session );
|
||||
// behind the session's back, let's modify the statuses to one
|
||||
scope.inSession( this::updateStatuses );
|
||||
}
|
||||
|
||||
// Now lets refresh the persistent batch, and see if the refresh cascaded to the jobs collection elements
|
||||
session.refresh( batch );
|
||||
|
||||
Iterator itr = batch.getJobs().iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
Job job = (Job) itr.next();
|
||||
assertEquals( 1, job.getStatus(), "Jobs not refreshed!" );
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void testRefreshCascade(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.refresh( batch );
|
||||
batch.jobs.forEach( job -> assertEquals( "Jobs not refreshed!", 1, job.status ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void updateStatuses(final SessionImplementor session) {
|
||||
session.doWork(
|
||||
connection -> {
|
||||
PreparedStatement stmnt = null;
|
||||
try {
|
||||
stmnt = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(
|
||||
"UPDATE T_JOB SET JOB_STATUS = 1" );
|
||||
session.getJdbcCoordinator().getResultSetReturn().executeUpdate( stmnt );
|
||||
}
|
||||
finally {
|
||||
if ( stmnt != null ) {
|
||||
try {
|
||||
session.getJdbcCoordinator().getResourceRegistry().release( stmnt );
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
}
|
||||
connection -> {
|
||||
Statement stmnt = null;
|
||||
try {
|
||||
stmnt = session.getJdbcCoordinator().getStatementPreparer().createStatement();
|
||||
stmnt.execute( "UPDATE T_JOB SET JOB_STATUS = 1" );
|
||||
}
|
||||
finally {
|
||||
if ( stmnt != null ) {
|
||||
try {
|
||||
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( stmnt );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity( name = "Job" )
|
||||
@Table( name = "T_JOB" )
|
||||
static class Job {
|
||||
|
||||
@Id @GeneratedValue
|
||||
Long id;
|
||||
|
||||
@ManyToOne( fetch = FetchType.LAZY )
|
||||
JobBatch batch;
|
||||
|
||||
@Column( name = "PI", nullable = false )
|
||||
String processingInstructions;
|
||||
|
||||
@Column( name = "JOB_STATUS", nullable = false )
|
||||
int status;
|
||||
|
||||
Job() {}
|
||||
|
||||
Job(JobBatch batch) {
|
||||
this.batch = batch;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity( name = "JobBatch" )
|
||||
@Table( name = "T_JOB_BATCH" )
|
||||
static class JobBatch {
|
||||
|
||||
@Id @GeneratedValue
|
||||
Long id;
|
||||
|
||||
@Column( nullable = false )
|
||||
@Temporal( TemporalType.TIMESTAMP )
|
||||
Date batchDate;
|
||||
|
||||
@OneToMany( mappedBy = "batch", fetch = FetchType.LAZY, cascade = CascadeType.ALL )
|
||||
@Fetch( FetchMode.SELECT )
|
||||
Set<Job> jobs = new HashSet<>();
|
||||
|
||||
JobBatch() {}
|
||||
|
||||
JobBatch(Date batchDate) {
|
||||
this.batchDate = batchDate;
|
||||
}
|
||||
|
||||
Job createJob() {
|
||||
Job job = new Job( this );
|
||||
jobs.add( job );
|
||||
return job;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue