Re-enabled more tests and fix issues with in predicate, sqmMultiTableMutationStrategy creation and other minor issues
This commit is contained in:
parent
eafebd016f
commit
ddb0be61d5
|
@ -391,7 +391,7 @@ comparisonOperator
|
|||
inList
|
||||
: ELEMENTS? LEFT_PAREN dotIdentifierSequence RIGHT_PAREN # PersistentCollectionReferenceInList
|
||||
| LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN # ExplicitTupleInList
|
||||
| expression # SubQueryInList
|
||||
| expression # SubQueryOrParamInList
|
||||
;
|
||||
|
||||
likeEscape
|
||||
|
|
|
@ -273,10 +273,10 @@ public class Column implements Selectable, Serializable, Cloneable {
|
|||
Type type = getValue().getType();
|
||||
|
||||
if ( type instanceof EntityType ) {
|
||||
type = getTypeForEntityValue( mapping, type );
|
||||
type = getTypeForEntityValue( mapping, type, getTypeIndex() );
|
||||
}
|
||||
if ( type instanceof ComponentType ) {
|
||||
type = getTypeForComponentValue( mapping, type );
|
||||
type = getTypeForComponentValue( mapping, type, getTypeIndex() );
|
||||
}
|
||||
return dialect.getDefaultSizeStrategy().resolveDefaultSize(
|
||||
( (JdbcMapping) type ).getSqlTypeDescriptor(),
|
||||
|
@ -284,20 +284,42 @@ public class Column implements Selectable, Serializable, Cloneable {
|
|||
);
|
||||
}
|
||||
|
||||
private Type getTypeForComponentValue(Mapping mapping, Type type) {
|
||||
type = ( (ComponentType) type ).getSubtypes()[getTypeIndex()];
|
||||
if ( type instanceof EntityType ) {
|
||||
type = getTypeForEntityValue( mapping, type );
|
||||
private Type getTypeForComponentValue(Mapping mapping, Type type, int typeIndex) {
|
||||
final Type[] subtypes = ( (ComponentType) type ).getSubtypes();
|
||||
int currentSubtypesColumnSpans = 0;
|
||||
for ( int i = 0; i <= subtypes.length; i++ ) {
|
||||
Type subtype = subtypes[i];
|
||||
int subtypeColumnSpan = subtype.getColumnSpan( mapping );
|
||||
currentSubtypesColumnSpans += subtypeColumnSpan;
|
||||
if ( currentSubtypesColumnSpans - 1 >= typeIndex ) {
|
||||
if ( subtype instanceof EntityType ) {
|
||||
return getTypeForEntityValue( mapping, subtype, subtypeColumnSpan - i );
|
||||
}
|
||||
if ( subtype instanceof ComponentType ) {
|
||||
return getTypeForComponentValue( mapping, subtype, subtypeColumnSpan - i );
|
||||
}
|
||||
if ( i == typeIndex ) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
|
||||
throw new HibernateException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Unable to resolve org.hibernate.type.Type for column `%s.%s`",
|
||||
getValue().getTable().getName(),
|
||||
getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private Type getTypeForEntityValue(Mapping mapping, Type type) {
|
||||
private Type getTypeForEntityValue(Mapping mapping, Type type, int typeIndex) {
|
||||
while ( !( type instanceof JdbcMapping ) ) {
|
||||
//ManyToOneType doesn't implement JdbcMapping
|
||||
type = mapping.getIdentifierType( ( (EntityType) type ).getAssociatedEntityName() );
|
||||
if ( type instanceof ComponentType ) {
|
||||
type = ( (ComponentType) type ).getSubtypes()[getTypeIndex()];
|
||||
type = ( (ComponentType) type ).getSubtypes()[typeIndex];
|
||||
}
|
||||
}
|
||||
return type;
|
||||
|
|
|
@ -383,6 +383,56 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DomainResult<T> createDomainResult(
|
||||
NavigablePath navigablePath,
|
||||
TableGroup tableGroup,
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
//noinspection unchecked
|
||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
|
||||
final String identificationVariable = tableReference.getIdentificationVariable();
|
||||
int size = keyColumnExpressions.size();
|
||||
List<SqlSelection> sqlSelections = new ArrayList<>(size);
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final String columnExpression = keyColumnExpressions.get( i );
|
||||
final JdbcMapping jdbcMapping = jdbcMappings.get( i );
|
||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
columnExpression
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
columnExpression,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
),
|
||||
jdbcMapping.getJavaTypeDescriptor(),
|
||||
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
sqlSelections.add( sqlSelection );
|
||||
}
|
||||
|
||||
return new EmbeddableForeignKeyResultImpl(
|
||||
sqlSelections,
|
||||
navigablePath,
|
||||
mappingType,
|
||||
resultVariable,
|
||||
creationState
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType findContainingEntityMapping() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -928,7 +928,7 @@ public class MappingModelCreationHelper {
|
|||
}
|
||||
else {
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
"Support for composite foreign keys not yet implemented: " + bootValueMapping.getRole()
|
||||
"Support for " + fkTarget.getClass() + " foreign keys not yet implemented: " + bootValueMapping.getRole()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
|
|||
Component bootCidDescriptor,
|
||||
Component bootIdClassDescriptor,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
// todo (6.0) : handle MapsId and IdClass
|
||||
// todo (6.0) : handle MapsId
|
||||
super(
|
||||
attributeMetadataAccess,
|
||||
embeddableDescriptor,
|
||||
|
|
|
@ -5924,15 +5924,7 @@ public abstract class AbstractEntityPersister
|
|||
accessOptimizer = null;
|
||||
}
|
||||
|
||||
if ( isMultiTable() ) {
|
||||
sqmMultiTableMutationStrategy = interpretSqmMultiTableStrategy(
|
||||
this,
|
||||
creationProcess
|
||||
);
|
||||
}
|
||||
else {
|
||||
sqmMultiTableMutationStrategy = null;
|
||||
}
|
||||
|
||||
|
||||
// register a callback for after all `#prepareMappingModel` calls have finished. here we want to delay the
|
||||
// generation of `staticFetchableList` because we need to wait until after all sub-classes have had their
|
||||
|
@ -5946,6 +5938,26 @@ public abstract class AbstractEntityPersister
|
|||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
if ( isMultiTable() ) {
|
||||
creationProcess.registerInitializationCallback(
|
||||
"Entity(" + getEntityName() + ") `sqmMultiTableMutationStrategy` interpretation",
|
||||
() -> {
|
||||
sqmMultiTableMutationStrategy = interpretSqmMultiTableStrategy(
|
||||
this,
|
||||
creationProcess
|
||||
);
|
||||
if ( sqmMultiTableMutationStrategy == null ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
sqmMultiTableMutationStrategy = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareMappingModel(MappingModelCreationProcess creationProcess, PersistentClass bootEntityDescriptor) {
|
||||
|
@ -6026,8 +6038,13 @@ public abstract class AbstractEntityPersister
|
|||
MappingModelCreationProcess creationProcess) {
|
||||
assert entityMappingDescriptor.isMultiTable();
|
||||
|
||||
if ( entityMappingDescriptor.getSuperMappingType() != null ) {
|
||||
return entityMappingDescriptor.getSuperMappingType().getSqmMultiTableMutationStrategy();
|
||||
EntityMappingType superMappingType = entityMappingDescriptor.getSuperMappingType();
|
||||
if ( superMappingType != null ) {
|
||||
SqmMultiTableMutationStrategy sqmMultiTableMutationStrategy = superMappingType
|
||||
.getSqmMultiTableMutationStrategy();
|
||||
if ( sqmMultiTableMutationStrategy != null ) {
|
||||
return sqmMultiTableMutationStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
// we need the boot model so we can have access to the Table
|
||||
|
|
|
@ -1407,8 +1407,12 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
final List<SqmExpression<?>> listExpressions = new ArrayList<>( expressionContexts.size() );
|
||||
for ( HqlParser.ExpressionContext expressionContext : expressionContexts ) {
|
||||
final Map<Class<?>, Enum<?>> possibleEnumValues;
|
||||
if ( isEnum && (possibleEnumValues = getPossibleEnumValues( expressionContext )) != null ) {
|
||||
listExpressions.add( resolveEnumShorthandLiteral( expressionContext, possibleEnumValues, testExpression.getJavaType() ) );
|
||||
if ( isEnum && ( possibleEnumValues = getPossibleEnumValues( expressionContext ) ) != null ) {
|
||||
listExpressions.add( resolveEnumShorthandLiteral(
|
||||
expressionContext,
|
||||
possibleEnumValues,
|
||||
testExpression.getJavaType()
|
||||
) );
|
||||
}
|
||||
else {
|
||||
listExpressions.add( (SqmExpression) expressionContext.accept( this ) );
|
||||
|
@ -1427,21 +1431,33 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
parameterDeclarationContextStack.pop();
|
||||
}
|
||||
}
|
||||
else if ( inListContext instanceof HqlParser.SubQueryInListContext ) {
|
||||
final HqlParser.SubQueryInListContext subQueryContext = (HqlParser.SubQueryInListContext) inListContext;
|
||||
final SqmExpression subQueryExpression = (SqmExpression) subQueryContext.expression().accept( this );
|
||||
else if ( inListContext instanceof HqlParser.SubQueryOrParamInListContext ) {
|
||||
final HqlParser.SubQueryOrParamInListContext subQueryOrParamInListContext = (HqlParser.SubQueryOrParamInListContext) inListContext;
|
||||
final SqmExpression sqmExpression = (SqmExpression) subQueryOrParamInListContext.expression().accept( this );
|
||||
|
||||
if ( !(subQueryExpression instanceof SqmSubQuery) ) {
|
||||
if ( !( sqmExpression instanceof SqmSubQuery ) ) {
|
||||
if ( sqmExpression instanceof SqmParameter ) {
|
||||
final List<SqmExpression<?>> listExpressions = new ArrayList<>( 1 );
|
||||
listExpressions.add( sqmExpression );
|
||||
|
||||
return new SqmInListPredicate(
|
||||
testExpression,
|
||||
listExpressions,
|
||||
ctx.NOT() != null,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
}
|
||||
throw new ParsingException(
|
||||
"Was expecting a SubQueryExpression, but found " + subQueryExpression.getClass().getSimpleName()
|
||||
+ " : " + subQueryContext.expression().toString()
|
||||
"Was expecting a SubQueryExpression or a SqmParameter, but found " + sqmExpression.getClass()
|
||||
.getSimpleName()
|
||||
+ " : " + subQueryOrParamInListContext.expression().toString()
|
||||
);
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return new SqmInSubQueryPredicate(
|
||||
testExpression,
|
||||
(SqmSubQuery) subQueryExpression,
|
||||
(SqmSubQuery) sqmExpression,
|
||||
ctx.NOT() != null,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
|
|
|
@ -8,22 +8,16 @@ package org.hibernate.query.sqm.tree.expression;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.persistence.criteria.Expression;
|
||||
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.criteria.JpaSelection;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmExpressable;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* Specialized SQM literal defined by an enum reference. E.g.
|
||||
|
@ -31,7 +25,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmEnumLiteral<E extends Enum<E>> extends AbstractSqmExpression<E> implements SqmExpression<E>, SqmExpressable<E>, SemanticPathPart {
|
||||
public class SqmEnumLiteral<E extends Enum<E>> extends AbstractSqmExpression<E> implements SqmExpressable<E>, SemanticPathPart {
|
||||
private final E enumValue;
|
||||
private final EnumJavaTypeDescriptor<E> referencedEnumTypeDescriptor;
|
||||
private final String enumValueName;
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|||
*/
|
||||
public class SqmLiteral<T>
|
||||
extends AbstractSqmExpression<T>
|
||||
implements SqmExpression<T>, DomainResultProducer<T> {
|
||||
implements DomainResultProducer<T> {
|
||||
private final T value;
|
||||
|
||||
public SqmLiteral(T value, SqmExpressable<T> inherentType, NodeBuilder nodeBuilder) {
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmSelfRenderingExpression<T> extends AbstractSqmExpression<T> implements SqmExpression<T> {
|
||||
public class SqmSelfRenderingExpression<T> extends AbstractSqmExpression<T> {
|
||||
private final Function<SemanticQueryWalker, Expression> renderer;
|
||||
|
||||
public SqmSelfRenderingExpression(
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.query.sqm.tree.predicate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.criteria.Expression;
|
||||
|
@ -71,6 +72,12 @@ public class SqmInListPredicate<T> extends AbstractNegatableSqmPredicate impleme
|
|||
|
||||
@Override
|
||||
public SqmInPredicate<T> value(Object value) {
|
||||
if ( value instanceof Collection ) {
|
||||
( (Collection) value ).forEach(
|
||||
v -> addExpression( nodeBuilder().literal( v ) )
|
||||
);
|
||||
return this;
|
||||
}
|
||||
addExpression( nodeBuilder().literal( value ) );
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.EmbeddedId;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.JoinColumn;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EmbeddedId;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.JoinColumn;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* 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.annotations.cid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.query.Query;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* test some composite id functionalities
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
Parent.class,
|
||||
Child.class,
|
||||
Channel.class,
|
||||
TvMagazin.class,
|
||||
TvProgramIdClass.class,
|
||||
TvProgram.class,
|
||||
Presenter.class,
|
||||
Order.class,
|
||||
Product.class,
|
||||
OrderLine.class,
|
||||
OrderLinePk.class,
|
||||
LittleGenius.class,
|
||||
A.class,
|
||||
B.class,
|
||||
C.class,
|
||||
SomeEntity.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class CompositeIdTest {
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope){
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete from LittleGenius" ).executeUpdate();
|
||||
session.createQuery( "delete from Child" ).executeUpdate();
|
||||
session.createQuery( "delete from Parent" ).executeUpdate();
|
||||
session.createQuery( "delete from SomeEntity" ).executeUpdate();
|
||||
session.createQuery( "delete from TvProgram" ).executeUpdate();
|
||||
session.createQuery( "delete from TvProgramIdClass" ).executeUpdate();
|
||||
session.createQuery( "delete from TvMagazin" ).executeUpdate();
|
||||
session.createQuery( "delete from Presenter" ).executeUpdate();
|
||||
session.createQuery( "delete from Channel" ).executeUpdate();
|
||||
session.createQuery( "delete from A" ).executeUpdate();
|
||||
session.createQuery( "delete from B" ).executeUpdate();
|
||||
session.createQuery( "delete from C" ).executeUpdate();
|
||||
session.createQuery( "delete from OrderLine" ).executeUpdate();
|
||||
session.createQuery( "delete from Product" ).executeUpdate();
|
||||
session.createQuery( "delete from Order" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneToOneInCompositePk(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
B b = new B();
|
||||
C c = new C();
|
||||
session.persist( b );
|
||||
session.persist( c );
|
||||
A a = new A();
|
||||
a.setAId( new AId() );
|
||||
a.getAId().setB( b );
|
||||
a.getAId().setC( c );
|
||||
session.persist( a );
|
||||
session.flush();
|
||||
session.clear();
|
||||
|
||||
a = session.get( A.class, a.getAId() );
|
||||
assertEquals( b.getId(), a.getAId().getB().getId() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This feature is not supported by the EJB3
|
||||
* this is an hibernate extension
|
||||
*/
|
||||
@Test
|
||||
public void testManyToOneInCompositePk(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
ParentPk ppk = new ParentPk();
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
session.persist( p );
|
||||
ChildPk cpk = new ChildPk();
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
Child c = new Child();
|
||||
c.id = cpk;
|
||||
session.persist( c );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Query q = session.createQuery( "select c from Child c where c.id.nthChild = :nth" );
|
||||
q.setParameter( "nth", 1 );
|
||||
List results = q.list();
|
||||
assertEquals( 1, results.size() );
|
||||
Child c = (Child) results.get( 0 );
|
||||
assertNotNull( c );
|
||||
assertNotNull( c.id.parent );
|
||||
//FIXME mke it work in unambigious cases
|
||||
// assertNotNull(c.id.parent.id);
|
||||
// assertEquals(p.id.getFirstName(), c.id.parent.id.getFirstName());
|
||||
session.delete( c );
|
||||
session.delete( c.id.parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testManyToOneInCompositePkInPC(SessionFactoryScope scope) {
|
||||
ParentPk ppk = new ParentPk();
|
||||
ChildPk cpk = new ChildPk();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
session.persist( p );
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
Child c = new Child();
|
||||
c.id = cpk;
|
||||
session.persist( c );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent p = session.get( Parent.class, ppk );
|
||||
// p.id should be ppk.
|
||||
assertSame( ppk, p.id );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Child c = session.get( Child.class, cpk );
|
||||
// c.id should be cpk
|
||||
assertSame( cpk, c.id );
|
||||
// only Child should be in PC (c.id.parent should not be in PC)
|
||||
assertTrue( session.getPersistenceContext().isEntryFor( c ) );
|
||||
assertFalse( session.getPersistenceContext().isEntryFor( c.id.parent ) );
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This feature is not supported by the EJB3
|
||||
* this is an hibernate extension
|
||||
*/
|
||||
@Test
|
||||
public void testManyToOneInCompositePkAndSubclass(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
ParentPk ppk = new ParentPk();
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
session.persist( p );
|
||||
ChildPk cpk = new ChildPk();
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
LittleGenius c = new LittleGenius();
|
||||
c.particularSkill = "Human Annotation parser";
|
||||
c.id = cpk;
|
||||
session.persist( c );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Query q = session.createQuery( "select c from Child c where c.id.nthChild = :nth" );
|
||||
q.setParameter( "nth", 1 );
|
||||
List results = q.list();
|
||||
assertEquals( 1, results.size() );
|
||||
Child c = (LittleGenius) results.get( 0 );
|
||||
assertNotNull( c );
|
||||
assertNotNull( c.id.parent );
|
||||
//FIXME mke it work in unambigious cases
|
||||
// assertNotNull(c.id.parent.id);
|
||||
// assertEquals(p.id.getFirstName(), c.id.parent.id.getFirstName());
|
||||
session.delete( c );
|
||||
session.delete( c.id.parent );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToOneInCompositeId(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Channel channel = new Channel();
|
||||
session.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Casimir";
|
||||
session.persist( pres );
|
||||
TvMagazinPk pk = new TvMagazinPk();
|
||||
TvMagazin mag = new TvMagazin();
|
||||
mag.time = new Date();
|
||||
mag.id = pk;
|
||||
pk.channel = channel;
|
||||
pk.presenter = pres;
|
||||
session.persist( mag );
|
||||
session.getTransaction().commit();
|
||||
session.clear();
|
||||
session.beginTransaction();
|
||||
mag = (TvMagazin) session.createQuery( "from TvMagazin mag" ).uniqueResult();
|
||||
assertNotNull( mag.id );
|
||||
assertNotNull( mag.id.channel );
|
||||
assertEquals( channel.id, mag.id.channel.id );
|
||||
assertNotNull( mag.id.presenter );
|
||||
assertEquals( pres.name, mag.id.presenter.name );
|
||||
session.delete( mag );
|
||||
session.delete( mag.id.channel );
|
||||
session.delete( mag.id.presenter );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToOneInCompositeIdClass(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order order = new Order();
|
||||
session.persist( order );
|
||||
Product product = new Product();
|
||||
product.name = "small car";
|
||||
session.persist( product );
|
||||
OrderLine orderLine = new OrderLine();
|
||||
orderLine.order = order;
|
||||
orderLine.product = product;
|
||||
session.persist( orderLine );
|
||||
session.flush();
|
||||
session.clear();
|
||||
|
||||
orderLine = (OrderLine) session.createQuery( "select ol from OrderLine ol" ).uniqueResult();
|
||||
assertNotNull( orderLine.order );
|
||||
assertEquals( order.id, orderLine.order.id );
|
||||
assertNotNull( orderLine.product );
|
||||
assertEquals( product.name, orderLine.product.name );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testManyToOneInCompositeIdClassInPC(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order order = new Order();
|
||||
session.persist( order );
|
||||
Product product = new Product();
|
||||
product.name = "small car";
|
||||
session.persist( product );
|
||||
OrderLine orderLine = new OrderLine();
|
||||
orderLine.order = order;
|
||||
orderLine.product = product;
|
||||
session.persist( orderLine );
|
||||
session.flush();
|
||||
session.clear();
|
||||
|
||||
session.clear();
|
||||
OrderLinePk orderLinePK = new OrderLinePk();
|
||||
orderLinePK.order = orderLine.order;
|
||||
orderLinePK.product = orderLine.product;
|
||||
orderLine = session.get( OrderLine.class, orderLinePK );
|
||||
assertTrue( orderLine.order != orderLinePK.order );
|
||||
assertTrue( orderLine.product != orderLinePK.product );
|
||||
assertTrue( session.getPersistenceContext().isEntryFor( orderLine ) );
|
||||
assertTrue( session.getPersistenceContext().isEntryFor( orderLine.order ) );
|
||||
assertTrue( session.getPersistenceContext().isEntryFor( orderLine.product ) );
|
||||
assertFalse( session.getPersistenceContext().isEntryFor( orderLinePK.order ) );
|
||||
assertFalse( session.getPersistenceContext().isEntryFor( orderLinePK.product ) );
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testGetWithUpdatedDetachedEntityInCompositeID(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Channel channel = new Channel();
|
||||
Presenter presenter = new Presenter();
|
||||
presenter.name = "Jane";
|
||||
TvMagazin tvMagazin = new TvMagazin();
|
||||
tvMagazin.id = new TvMagazinPk();
|
||||
tvMagazin.id.channel = channel;
|
||||
tvMagazin.id.presenter = presenter;
|
||||
session.persist( channel );
|
||||
session.persist( presenter );
|
||||
session.persist( tvMagazin );
|
||||
session.flush();
|
||||
|
||||
session.clear();
|
||||
// update channel
|
||||
channel.name = "chnl";
|
||||
TvMagazinPk pkNew = new TvMagazinPk();
|
||||
// set pkNew.channel to the unmerged copy.
|
||||
pkNew.channel = channel;
|
||||
pkNew.presenter = presenter;
|
||||
// the following fails because there is already a managed channel
|
||||
tvMagazin = session.get( TvMagazin.class, pkNew );
|
||||
channel = session.get( Channel.class, channel.id );
|
||||
assertNull( channel.name );
|
||||
session.flush();
|
||||
session.clear();
|
||||
|
||||
// make sure that channel.name is still null
|
||||
channel = session.get( Channel.class, channel.id );
|
||||
assertNull( channel.name );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testGetWithDetachedEntityInCompositeIDWithManagedCopy(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Channel channel = new Channel();
|
||||
Presenter presenter = new Presenter();
|
||||
presenter.name = "Jane";
|
||||
TvMagazin tvMagazin = new TvMagazin();
|
||||
tvMagazin.id = new TvMagazinPk();
|
||||
tvMagazin.id.channel = channel;
|
||||
tvMagazin.id.presenter = presenter;
|
||||
session.persist( channel );
|
||||
session.persist( presenter );
|
||||
session.persist( tvMagazin );
|
||||
session.flush();
|
||||
|
||||
session.clear();
|
||||
// merge channel to put channel back in PersistenceContext
|
||||
session.merge( channel );
|
||||
TvMagazinPk pkNew = new TvMagazinPk();
|
||||
// set pkNew.channel to the unmerged copy.
|
||||
pkNew.channel = channel;
|
||||
pkNew.presenter = presenter;
|
||||
// the following fails because there is already a managed channel
|
||||
tvMagazin = session.get( TvMagazin.class, pkNew );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondaryTableWithCompositeId(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Channel channel = new Channel();
|
||||
session.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Tim Russet";
|
||||
session.persist( pres );
|
||||
TvMagazinPk pk = new TvMagazinPk();
|
||||
TvProgram program = new TvProgram();
|
||||
program.time = new Date();
|
||||
program.id = pk;
|
||||
program.text = "Award Winning Programming";
|
||||
pk.channel = channel;
|
||||
pk.presenter = pres;
|
||||
session.persist( program );
|
||||
session.getTransaction().commit();
|
||||
session.clear();
|
||||
session.beginTransaction();
|
||||
program = (TvProgram) session.createQuery( "from TvProgram pr" ).uniqueResult();
|
||||
assertNotNull( program.id );
|
||||
assertNotNull( program.id.channel );
|
||||
assertEquals( channel.id, program.id.channel.id );
|
||||
assertNotNull( program.id.presenter );
|
||||
assertNotNull( program.text );
|
||||
assertEquals( pres.name, program.id.presenter.name );
|
||||
session.delete( program );
|
||||
session.delete( program.id.channel );
|
||||
session.delete( program.id.presenter );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondaryTableWithIdClass(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Channel channel = new Channel();
|
||||
session.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Bob";
|
||||
session.persist( pres );
|
||||
TvProgramIdClass program = new TvProgramIdClass();
|
||||
program.time = new Date();
|
||||
program.channel = channel;
|
||||
program.presenter = pres;
|
||||
program.text = "Jump the shark programming";
|
||||
session.persist( program );
|
||||
session.getTransaction().commit();
|
||||
session.clear();
|
||||
session.beginTransaction();
|
||||
program = (TvProgramIdClass) session.createQuery( "from TvProgramIdClass pr" ).uniqueResult();
|
||||
assertNotNull( program.channel );
|
||||
assertEquals( channel.id, program.channel.id );
|
||||
assertNotNull( program.presenter );
|
||||
assertNotNull( program.text );
|
||||
assertEquals( pres.name, program.presenter.name );
|
||||
session.delete( program );
|
||||
session.delete( program.channel );
|
||||
session.delete( program.presenter );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected(reason = "Criteria add IdClass id as predicate value has not yet been implemented")
|
||||
public void testQueryInAndComposite(SessionFactoryScope scope) {
|
||||
|
||||
scope.inTransaction(
|
||||
s -> {
|
||||
createData( s );
|
||||
s.flush();
|
||||
List ids = new ArrayList<SomeEntityId>( 2 );
|
||||
ids.add( new SomeEntityId( 1, 12 ) );
|
||||
ids.add( new SomeEntityId( 10, 23 ) );
|
||||
|
||||
CriteriaBuilder criteriaBuilder = s.getCriteriaBuilder();
|
||||
CriteriaQuery<SomeEntity> criteria = criteriaBuilder.createQuery( SomeEntity.class );
|
||||
Root<SomeEntity> root = criteria.from( SomeEntity.class );
|
||||
CriteriaBuilder.In<Object> inPredicate = criteriaBuilder.in( root.get( "id" ) );
|
||||
criteria.where( criteriaBuilder.or( inPredicate.value( ids ) ) );
|
||||
List list = s.createQuery( criteria ).list();
|
||||
|
||||
// Criteria criteria = s.createCriteria( SomeEntity.class );
|
||||
// Disjunction disjunction = Restrictions.disjunction();
|
||||
//
|
||||
// disjunction.add( Restrictions.in( "id", ids ) );
|
||||
// criteria.add( disjunction );
|
||||
//
|
||||
// List list = criteria.list();
|
||||
assertEquals( 2, list.size() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryInAndCompositeWithHQL(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
createData( session );
|
||||
session.flush();
|
||||
List<SomeEntityId> ids = new ArrayList<>( 2 );
|
||||
ids.add( new SomeEntityId( 1, 12 ) );
|
||||
ids.add( new SomeEntityId( 10, 23 ) );
|
||||
ids.add( new SomeEntityId( 10, 22 ) );
|
||||
Query query = session.createQuery( "from SomeEntity e where e.id in (:idList)" );
|
||||
query.setParameterList( "idList", ids );
|
||||
List list = query.list();
|
||||
assertEquals( 3, list.size() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void createData(Session s) {
|
||||
SomeEntity someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId() );
|
||||
someEntity.getId().setId( 1 );
|
||||
someEntity.getId().setVersion( 11 );
|
||||
someEntity.setProp( "aa" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId() );
|
||||
someEntity.getId().setId( 1 );
|
||||
someEntity.getId().setVersion( 12 );
|
||||
someEntity.setProp( "bb" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId() );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 21 );
|
||||
someEntity.setProp( "cc1" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId() );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 22 );
|
||||
someEntity.setProp( "cc2" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId() );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 23 );
|
||||
someEntity.setProp( "cc3" );
|
||||
s.persist( someEntity );
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.PrimaryKeyJoinColumns;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Column;
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Entity;
|
|
@ -4,7 +4,8 @@
|
|||
* 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.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
|
@ -27,10 +28,6 @@ public class SomeEntityId implements Serializable {
|
|||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i
|
||||
* @param j
|
||||
*/
|
||||
public SomeEntityId(int id, int version) {
|
||||
super();
|
||||
this.id = id;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.util.Date;
|
||||
import javax.persistence.AssociationOverride;
|
||||
import javax.persistence.AssociationOverrides;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.JoinColumn;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.util.Date;
|
||||
import javax.persistence.AssociationOverride;
|
||||
import javax.persistence.AssociationOverrides;
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$Id$
|
||||
package org.hibernate.test.annotations.cid;
|
||||
package org.hibernate.orm.test.annotations.cid;
|
||||
import java.util.Date;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
|
@ -1,526 +0,0 @@
|
|||
/*
|
||||
* 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.test.annotations.cid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* test some composite id functionalities
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class CompositeIdTest extends BaseCoreFunctionalTestCase {
|
||||
@Test
|
||||
public void testOneToOneInCompositePk() throws Exception {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
B b = new B();
|
||||
C c = new C();
|
||||
s.persist( b );
|
||||
s.persist( c );
|
||||
A a = new A();
|
||||
a.setAId( new AId() );
|
||||
a.getAId().setB( b );
|
||||
a.getAId().setC( c );
|
||||
s.persist( a );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
||||
a = (A) s.get(A.class, a.getAId() );
|
||||
assertEquals( b.getId(), a.getAId().getB().getId() );
|
||||
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This feature is not supported by the EJB3
|
||||
* this is an hibernate extension
|
||||
*/
|
||||
@Test
|
||||
public void testManyToOneInCompositePk() throws Exception {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
ParentPk ppk = new ParentPk();
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
s.persist( p );
|
||||
ChildPk cpk = new ChildPk();
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
Child c = new Child();
|
||||
c.id = cpk;
|
||||
s.persist( c );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
Query q = s.createQuery( "select c from Child c where c.id.nthChild = :nth" );
|
||||
q.setParameter( "nth", 1 );
|
||||
List results = q.list();
|
||||
assertEquals( 1, results.size() );
|
||||
c = (Child) results.get( 0 );
|
||||
assertNotNull( c );
|
||||
assertNotNull( c.id.parent );
|
||||
//FIXME mke it work in unambigious cases
|
||||
// assertNotNull(c.id.parent.id);
|
||||
// assertEquals(p.id.getFirstName(), c.id.parent.id.getFirstName());
|
||||
s.delete( c );
|
||||
s.delete( c.id.parent );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-10476")
|
||||
public void testManyToOneInCompositePkInPC() throws Exception {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
ParentPk ppk = new ParentPk();
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
s.persist( p );
|
||||
ChildPk cpk = new ChildPk();
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
Child c = new Child();
|
||||
c.id = cpk;
|
||||
s.persist( c );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
p = (Parent) s.get( Parent.class, ppk);
|
||||
// p.id should be ppk.
|
||||
assertSame( ppk, p.id );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
c = (Child) s.get( Child.class, cpk );
|
||||
// c.id should be cpk
|
||||
assertSame( cpk, c.id );
|
||||
// only Child should be in PC (c.id.parent should not be in PC)
|
||||
SessionImplementor sessionImplementor = (SessionImplementor) s;
|
||||
assertTrue( sessionImplementor.getPersistenceContext().isEntryFor( c ) );
|
||||
assertFalse( sessionImplementor.getPersistenceContext().isEntryFor( c.id.parent ) );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This feature is not supported by the EJB3
|
||||
* this is an hibernate extension
|
||||
*/
|
||||
@Test
|
||||
public void testManyToOneInCompositePkAndSubclass() throws Exception {
|
||||
Session s;
|
||||
Transaction tx;
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
ParentPk ppk = new ParentPk();
|
||||
ppk.setFirstName( "Emmanuel" );
|
||||
ppk.setLastName( "Bernard" );
|
||||
Parent p = new Parent();
|
||||
p.id = ppk;
|
||||
s.persist( p );
|
||||
ChildPk cpk = new ChildPk();
|
||||
cpk.parent = p;
|
||||
cpk.nthChild = 1;
|
||||
LittleGenius c = new LittleGenius();
|
||||
c.particularSkill = "Human Annotation parser";
|
||||
c.id = cpk;
|
||||
s.persist( c );
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
Query q = s.createQuery( "select c from Child c where c.id.nthChild = :nth" );
|
||||
q.setParameter( "nth", 1 );
|
||||
List results = q.list();
|
||||
assertEquals( 1, results.size() );
|
||||
c = (LittleGenius) results.get( 0 );
|
||||
assertNotNull( c );
|
||||
assertNotNull( c.id.parent );
|
||||
//FIXME mke it work in unambigious cases
|
||||
// assertNotNull(c.id.parent.id);
|
||||
// assertEquals(p.id.getFirstName(), c.id.parent.id.getFirstName());
|
||||
s.delete( c );
|
||||
s.delete( c.id.parent );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToOneInCompositeId() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Channel channel = new Channel();
|
||||
s.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Casimir";
|
||||
s.persist( pres );
|
||||
TvMagazinPk pk = new TvMagazinPk();
|
||||
TvMagazin mag = new TvMagazin();
|
||||
mag.time = new Date();
|
||||
mag.id = pk;
|
||||
pk.channel = channel;
|
||||
pk.presenter = pres;
|
||||
s.persist( mag );
|
||||
tx.commit();
|
||||
s.clear();
|
||||
tx = s.beginTransaction();
|
||||
mag = (TvMagazin) s.createQuery( "from TvMagazin mag" ).uniqueResult();
|
||||
assertNotNull( mag.id );
|
||||
assertNotNull( mag.id.channel );
|
||||
assertEquals( channel.id, mag.id.channel.id );
|
||||
assertNotNull( mag.id.presenter );
|
||||
assertEquals( pres.name, mag.id.presenter.name );
|
||||
s.delete( mag );
|
||||
s.delete( mag.id.channel );
|
||||
s.delete( mag.id.presenter );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToOneInCompositeIdClass() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Order order = new Order();
|
||||
s.persist( order );
|
||||
Product product = new Product();
|
||||
product.name = "small car";
|
||||
s.persist( product );
|
||||
OrderLine orderLine = new OrderLine();
|
||||
orderLine.order = order;
|
||||
orderLine.product = product;
|
||||
s.persist( orderLine );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
||||
orderLine = (OrderLine) s.createQuery( "select ol from OrderLine ol" ).uniqueResult();
|
||||
assertNotNull( orderLine.order );
|
||||
assertEquals( order.id, orderLine.order.id );
|
||||
assertNotNull( orderLine.product );
|
||||
assertEquals( product.name, orderLine.product.name );
|
||||
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testManyToOneInCompositeIdClassInPC() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Order order = new Order();
|
||||
s.persist( order );
|
||||
Product product = new Product();
|
||||
product.name = "small car";
|
||||
s.persist( product );
|
||||
OrderLine orderLine = new OrderLine();
|
||||
orderLine.order = order;
|
||||
orderLine.product = product;
|
||||
s.persist( orderLine );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
||||
s.clear();
|
||||
OrderLinePk orderLinePK = new OrderLinePk();
|
||||
orderLinePK.order = orderLine.order;
|
||||
orderLinePK.product = orderLine.product;
|
||||
orderLine = (OrderLine) s.get( OrderLine.class, orderLinePK );
|
||||
assertTrue( orderLine.order != orderLinePK.order );
|
||||
assertTrue( orderLine.product != orderLinePK.product );
|
||||
SessionImplementor sessionImplementor = (SessionImplementor) s;
|
||||
assertTrue( sessionImplementor.getPersistenceContext().isEntryFor( orderLine ) );
|
||||
assertTrue( sessionImplementor.getPersistenceContext().isEntryFor( orderLine.order ) );
|
||||
assertTrue( sessionImplementor.getPersistenceContext().isEntryFor( orderLine.product ) );
|
||||
assertFalse( sessionImplementor.getPersistenceContext().isEntryFor( orderLinePK.order ) );
|
||||
assertFalse( sessionImplementor.getPersistenceContext().isEntryFor( orderLinePK.product ) );
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testGetWithUpdatedDetachedEntityInCompositeID() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Channel channel = new Channel();
|
||||
Presenter presenter = new Presenter();
|
||||
presenter.name = "Jane";
|
||||
TvMagazin tvMagazin = new TvMagazin();
|
||||
tvMagazin.id = new TvMagazinPk();
|
||||
tvMagazin.id.channel = channel;
|
||||
tvMagazin.id.presenter = presenter;
|
||||
s.persist( channel );
|
||||
s.persist( presenter );
|
||||
s.persist( tvMagazin );
|
||||
s.flush();
|
||||
|
||||
s.clear();
|
||||
// update channel
|
||||
channel.name = "chnl";
|
||||
TvMagazinPk pkNew = new TvMagazinPk();
|
||||
// set pkNew.channel to the unmerged copy.
|
||||
pkNew.channel = channel;
|
||||
pkNew.presenter = presenter;
|
||||
// the following fails because there is already a managed channel
|
||||
tvMagazin = s.get( TvMagazin.class, pkNew );
|
||||
channel = s.get( Channel.class, channel.id );
|
||||
assertNull( channel.name );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
||||
// make sure that channel.name is still null
|
||||
channel = s.get( Channel.class, channel.id );
|
||||
assertNull( channel.name );
|
||||
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-10476")
|
||||
public void testGetWithDetachedEntityInCompositeIDWithManagedCopy() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Channel channel = new Channel();
|
||||
Presenter presenter = new Presenter();
|
||||
presenter.name = "Jane";
|
||||
TvMagazin tvMagazin = new TvMagazin();
|
||||
tvMagazin.id = new TvMagazinPk();
|
||||
tvMagazin.id.channel = channel;
|
||||
tvMagazin.id.presenter = presenter;
|
||||
s.persist( channel );
|
||||
s.persist( presenter );
|
||||
s.persist( tvMagazin );
|
||||
s.flush();
|
||||
|
||||
s.clear();
|
||||
// merge channel to put channel back in PersistenceContext
|
||||
s.merge( channel );
|
||||
TvMagazinPk pkNew = new TvMagazinPk();
|
||||
// set pkNew.channel to the unmerged copy.
|
||||
pkNew.channel = channel;
|
||||
pkNew.presenter = presenter;
|
||||
// the following fails because there is already a managed channel
|
||||
tvMagazin = s.get( TvMagazin.class, pkNew );
|
||||
tx.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondaryTableWithCompositeId() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Channel channel = new Channel();
|
||||
s.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Tim Russet";
|
||||
s.persist( pres );
|
||||
TvMagazinPk pk = new TvMagazinPk();
|
||||
TvProgram program = new TvProgram();
|
||||
program.time = new Date();
|
||||
program.id = pk;
|
||||
program.text = "Award Winning Programming";
|
||||
pk.channel = channel;
|
||||
pk.presenter = pres;
|
||||
s.persist( program );
|
||||
tx.commit();
|
||||
s.clear();
|
||||
tx = s.beginTransaction();
|
||||
program = (TvProgram) s.createQuery( "from TvProgram pr" ).uniqueResult();
|
||||
assertNotNull( program.id );
|
||||
assertNotNull( program.id.channel );
|
||||
assertEquals( channel.id, program.id.channel.id );
|
||||
assertNotNull( program.id.presenter );
|
||||
assertNotNull( program.text );
|
||||
assertEquals( pres.name, program.id.presenter.name );
|
||||
s.delete( program );
|
||||
s.delete( program.id.channel );
|
||||
s.delete( program.id.presenter );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondaryTableWithIdClass() throws Exception {
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
Channel channel = new Channel();
|
||||
s.persist( channel );
|
||||
Presenter pres = new Presenter();
|
||||
pres.name = "Bob";
|
||||
s.persist( pres );
|
||||
TvProgramIdClass program = new TvProgramIdClass();
|
||||
program.time = new Date();
|
||||
program.channel = channel;
|
||||
program.presenter = pres;
|
||||
program.text = "Jump the shark programming";
|
||||
s.persist( program );
|
||||
tx.commit();
|
||||
s.clear();
|
||||
tx = s.beginTransaction();
|
||||
program = (TvProgramIdClass) s.createQuery( "from TvProgramIdClass pr" ).uniqueResult();
|
||||
assertNotNull( program.channel );
|
||||
assertEquals( channel.id, program.channel.id );
|
||||
assertNotNull( program.presenter );
|
||||
assertNotNull( program.text );
|
||||
assertEquals( pres.name, program.presenter.name );
|
||||
s.delete( program );
|
||||
s.delete( program.channel );
|
||||
s.delete( program.presenter );
|
||||
tx.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryInAndComposite() {
|
||||
|
||||
inTransaction(
|
||||
s -> {
|
||||
createData( s );
|
||||
s.flush();
|
||||
List ids = new ArrayList<SomeEntityId>(2);
|
||||
ids.add( new SomeEntityId(1,12) );
|
||||
ids.add( new SomeEntityId(10,23) );
|
||||
|
||||
CriteriaBuilder criteriaBuilder = s.getCriteriaBuilder();
|
||||
CriteriaQuery<SomeEntity> criteria = criteriaBuilder.createQuery( SomeEntity.class );
|
||||
Root<SomeEntity> root = criteria.from( SomeEntity.class );
|
||||
criteria.where( criteriaBuilder.or( criteriaBuilder.in( root.get( "id" )).value( ids) ) );
|
||||
List list = s.createQuery( criteria ).list();
|
||||
|
||||
// Criteria criteria = s.createCriteria( SomeEntity.class );
|
||||
// Disjunction disjunction = Restrictions.disjunction();
|
||||
//
|
||||
// disjunction.add( Restrictions.in( "id", ids ) );
|
||||
// criteria.add( disjunction );
|
||||
//
|
||||
// List list = criteria.list();
|
||||
assertEquals( 2, list.size() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryInAndCompositeWithHQL() {
|
||||
Session s = openSession( );
|
||||
Transaction transaction = s.beginTransaction();
|
||||
createData( s );
|
||||
s.flush();
|
||||
List ids = new ArrayList<SomeEntityId>(2);
|
||||
ids.add( new SomeEntityId(1,12) );
|
||||
ids.add( new SomeEntityId(10,23) );
|
||||
ids.add( new SomeEntityId(10,22) );
|
||||
Query query=s.createQuery( "from SomeEntity e where e.id in :idList" );
|
||||
query.setParameterList( "idList", ids );
|
||||
List list=query.list();
|
||||
assertEquals( 3, list.size() );
|
||||
transaction.rollback();
|
||||
s.close();
|
||||
}
|
||||
|
||||
private void createData(Session s){
|
||||
SomeEntity someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId( ) );
|
||||
someEntity.getId().setId( 1 );
|
||||
someEntity.getId().setVersion( 11 );
|
||||
someEntity.setProp( "aa" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId( ) );
|
||||
someEntity.getId().setId( 1 );
|
||||
someEntity.getId().setVersion( 12 );
|
||||
someEntity.setProp( "bb" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId( ) );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 21 );
|
||||
someEntity.setProp( "cc1" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId( ) );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 22 );
|
||||
someEntity.setProp( "cc2" );
|
||||
s.persist( someEntity );
|
||||
|
||||
someEntity = new SomeEntity();
|
||||
someEntity.setId( new SomeEntityId( ) );
|
||||
someEntity.getId().setId( 10 );
|
||||
someEntity.getId().setVersion( 23 );
|
||||
someEntity.setProp( "cc3" );
|
||||
s.persist( someEntity );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
Parent.class,
|
||||
Child.class,
|
||||
Channel.class,
|
||||
TvMagazin.class,
|
||||
TvProgramIdClass.class,
|
||||
TvProgram.class,
|
||||
Presenter.class,
|
||||
Order.class,
|
||||
Product.class,
|
||||
OrderLine.class,
|
||||
OrderLinePk.class,
|
||||
LittleGenius.class,
|
||||
A.class,
|
||||
B.class,
|
||||
C.class,
|
||||
SomeEntity.class
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue