Fix @ElementCollection + @OrderBy with Inheritance

This commit is contained in:
Andrea Boriero 2020-07-28 18:32:34 +01:00
parent b9612247f5
commit 8db9709408
13 changed files with 512 additions and 385 deletions

View File

@ -211,11 +211,6 @@ public abstract class AbstractCompositeIdentifierMapping
return getEntityMapping().getRepresentationStrategy().getInstantiator().instantiate( sessionFactory );
}
@Override
public SingularAttributeMapping getParentInjectionAttributeMapping() {
return null;
}
@Override
public EntityMappingType findContainingEntityMapping() {
return entityMapping;

View File

@ -13,6 +13,7 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
@ -168,6 +169,12 @@ public class EntityCollectionPart
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public void visitColumns(ColumnConsumer consumer) {
entityMappingType.visitColumns( consumer );
}
@Override
public void applySqlSelections(
NavigablePath navigablePath,

View File

@ -7,18 +7,24 @@
package org.hibernate.metamodel.mapping.ordering.ast;
import org.hibernate.SortOrder;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.ordering.TranslationContext;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SortSpecification;
/**
* Represents a column-reference used in an order-by fragment
*
* @author Steve Ebersole
* @apiNote This is Hibernate-specific feature. For {@link javax.persistence.OrderBy} (JPA)
* all path references are expected to be domain paths (attributes).
*
@ -58,16 +64,18 @@ public class ColumnReference implements OrderingExpression, SequencePart {
String collation,
SortOrder sortOrder,
SqlAstCreationState creationState) {
final TableReference primaryTableReference = tableGroup.getPrimaryTableReference();
TableReference tableReference;
tableReference = getTableReference( tableGroup );
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
ast.addSortSpecification(
new SortSpecification(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( primaryTableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ),
sqlAstProcessingState -> new org.hibernate.sql.ast.tree.expression.ColumnReference(
tableGroup.getPrimaryTableReference(),
tableReference,
columnExpression,
isColumnExpressionFormula,
// because these ordering fragments are only ever part of the order-by clause, there
@ -81,4 +89,29 @@ public class ColumnReference implements OrderingExpression, SequencePart {
)
);
}
TableReference getTableReference(TableGroup tableGroup) {
ModelPartContainer modelPart = tableGroup.getModelPart();
if ( modelPart instanceof PluralAttributeMapping ) {
MappingType partMappingType = ( (PluralAttributeMapping) modelPart ).getElementDescriptor()
.getPartMappingType();
if ( partMappingType instanceof AbstractEntityPersister ) {
AbstractEntityPersister abstractEntityPersister = (AbstractEntityPersister) partMappingType;
int i = abstractEntityPersister.determineTableNumberForColumn( columnExpression );
String tableName = abstractEntityPersister.getTableName( i );
for ( TableReferenceJoin tableReferenceJoin : tableGroup.getTableReferenceJoins() ) {
final TableReference joinedTableReference = tableReferenceJoin.getJoinedTableReference();
if ( joinedTableReference.getTableExpression()
.equals( tableName ) ) {
return joinedTableReference;
}
}
}
else {
return tableGroup.getPrimaryTableReference();
}
}
return null;
}
}

View File

@ -52,8 +52,21 @@ public class PluralAttributePath implements DomainPath {
final ModelPart subPart = pluralAttributeMapping.findSubPart( name, null );
if ( subPart != null ) {
assert subPart instanceof CollectionPart;
return new CollectionPartPath( this, (CollectionPart) subPart );
if ( subPart instanceof CollectionPart ) {
return new CollectionPartPath( this, (CollectionPart) subPart );
}
else if ( !( subPart instanceof EmbeddableValuedModelPart ) ) {
final CollectionPartPath elementPath = new CollectionPartPath(
this,
pluralAttributeMapping.getElementDescriptor()
);
return new DomainPathContinuation(
elementPath.getNavigablePath().append( name ),
this,
pluralAttributeMapping.getElementDescriptor()
);
}
}
// the above checks for explicit element or index descriptor references

View File

@ -133,6 +133,7 @@ import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
@ -6441,6 +6442,13 @@ public abstract class AbstractEntityPersister
}
}
@Override
public void visitColumns(ColumnConsumer consumer) {
getAttributeMappings().forEach(
attributeMapping -> attributeMapping.visitColumns( consumer )
);
}
@Override
public void visitSubTypeAttributeMappings(Consumer<AttributeMapping> action) {
if ( subclassMappingTypes != null ) {

View File

@ -1241,7 +1241,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
@Override
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
if(hasSubclasses()) {
if ( hasSubclasses() ) {
if ( explicitDiscriminatorColumnName == null ) {
CaseSearchedExpressionInfo info = getCaseSearchedExpression( tableGroup );
return new JoinedSubclassDiscriminatorMappingImpl(
@ -1291,34 +1291,38 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
final BasicType discriminatorType = (BasicType) getDiscriminatorType();
final CaseSearchedExpression caseSearchedExpression = new CaseSearchedExpression( discriminatorType );
discriminatorValuesByTableName.forEach(
(tableName, discriminatorValue) -> {
if ( ! primaryTableReference.getTableExpression().equals( tableName ) ) {
TableReference tableReference = entityTableGroup.getTableReference( tableName );
if ( tableReference == null ) {
// we have not yet created a TableReference for this sub-class table, but we need to because
// it has a discriminator value associated with it
tableReference = entityTableGroup.resolveTableReference( tableName );
}
final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference );
info.columnReferences.add( identifierColumnReference );
addWhen(
caseSearchedExpression,
tableReference,
identifierColumnReference,
discriminatorType
);
}
Boolean addPrimaryTableCaseAsLastCaseExpression = false;
for ( String tableName : discriminatorValuesByTableName.keySet() ) {
if ( !primaryTableReference.getTableExpression().equals( tableName ) ) {
TableReference tableReference = entityTableGroup.getTableReference( tableName );
if ( tableReference == null ) {
// we have not yet created a TableReference for this sub-class table, but we need to because
// it has a discriminator value associated with it
tableReference = entityTableGroup.resolveTableReference( tableName );
}
);
addWhen(
caseSearchedExpression,
primaryTableReference,
getIdentifierColumnReference( primaryTableReference ),
discriminatorType
);
final ColumnReference identifierColumnReference = getIdentifierColumnReference( tableReference );
info.columnReferences.add( identifierColumnReference );
addWhen(
caseSearchedExpression,
tableReference,
identifierColumnReference,
discriminatorType
);
}
else {
addPrimaryTableCaseAsLastCaseExpression = true;
}
}
if ( addPrimaryTableCaseAsLastCaseExpression ) {
addWhen(
caseSearchedExpression,
primaryTableReference,
getIdentifierColumnReference( primaryTableReference ),
discriminatorType
);
}
info.caseSearchedExpression = caseSearchedExpression;
return info;

View File

@ -93,29 +93,25 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
@Override
public void resolveKey(RowProcessingState rowProcessingState) {
// todo (6.0) : register "parent resolution listener" if the composite is defined for `@Parent`
// something like:
final PropertyAccess parentInjectionPropertyAccess = embeddedModelPartDescriptor.getParentInjectionAttributePropertyAccess();
if ( parentInjectionPropertyAccess != null ) {
if ( getFetchParentAccess() != null ) {
getFetchParentAccess().findFirstEntityDescriptorAccess().registerResolutionListener(
// todo (6.0) : this is the legacy behavior
// - the first entity is injected as the parent, even if the composite
// is defined on another composite
owner -> {
if ( compositeInstance == null ) {
return;
}
parentInjectionPropertyAccess.getSetter().set(
compositeInstance,
owner,
rowProcessingState.getSession().getFactory()
);
final FetchParentAccess fetchParentAccess = getFetchParentAccess();
if ( parentInjectionPropertyAccess != null && fetchParentAccess != null ) {
fetchParentAccess.findFirstEntityDescriptorAccess().registerResolutionListener(
// todo (6.0) : this is the legacy behavior
// - the first entity is injected as the parent, even if the composite
// is defined on another composite
owner -> {
if ( compositeInstance == null ) {
return;
}
);
}
parentInjectionPropertyAccess.getSetter().set(
compositeInstance,
owner,
rowProcessingState.getSession().getFactory()
);
}
);
}
}
@ -137,7 +133,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
final PropertyAccess parentInjectionPropertyAccess = embeddedModelPartDescriptor.getParentInjectionAttributePropertyAccess();
if ( parentInjectionPropertyAccess != null && getFetchParentAccess() == null ) {
if ( parentInjectionPropertyAccess != null ) {
Initializer initializer = rowProcessingState.resolveInitializer( navigablePath.getParent() );
final Object owner;
if ( initializer instanceof CollectionInitializer ) {

View File

@ -12,7 +12,6 @@ import java.util.List;
import java.util.Locale;
import org.hibernate.Filter;
import org.hibernate.Transaction;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.mapping.Collection;
@ -65,144 +64,114 @@ public class DefaultNamingCollectionElementTest {
scope.getMetadataImplementor().getCollectionBinding( Boy.class.getName() + '.' + "favoriteNumbers" )
.getCollectionTable().getName()
);
scope.inSession(
scope.inTransaction(
session -> {
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
boy.getNickNames().add( "Johnny" );
boy.getNickNames().add( "Thing" );
boy.getScorePerNickName().put( "Johnny", 3 );
boy.getScorePerNickName().put( "Thing", 5 );
int[] favNbrs = new int[4];
for ( int index = 0; index < favNbrs.length - 1; index++ ) {
favNbrs[index] = index * 3;
}
boy.setFavoriteNumbers( favNbrs );
boy.getCharacters().add( Character.GENTLE );
boy.getCharacters().add( Character.CRAFTY );
HashMap<String, FavoriteFood> foods = new HashMap<>();
foods.put( "breakfast", FavoriteFood.PIZZA );
foods.put( "lunch", FavoriteFood.KUNGPAOCHICKEN );
foods.put( "dinner", FavoriteFood.SUSHI );
boy.setFavoriteFood( foods );
session.persist( boy );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy.getNickNames() );
assertTrue( boy.getNickNames().contains( "Thing" ) );
assertNotNull( boy.getScorePerNickName() );
assertTrue( boy.getScorePerNickName().containsKey( "Thing" ) );
assertEquals( Integer.valueOf( 5 ), boy.getScorePerNickName().get( "Thing" ) );
assertNotNull( boy.getFavoriteNumbers() );
assertEquals( 3, boy.getFavoriteNumbers()[1] );
assertTrue( boy.getCharacters().contains( Character.CRAFTY ) );
assertTrue( boy.getFavoriteFood().get( "dinner" ).equals( FavoriteFood.SUSHI ) );
assertTrue( boy.getFavoriteFood().get( "lunch" ).equals( FavoriteFood.KUNGPAOCHICKEN ) );
assertTrue( boy.getFavoriteFood().get( "breakfast" ).equals( FavoriteFood.PIZZA ) );
List result = session.createQuery(
"select boy from Boy boy join boy.nickNames names where names = :name" )
.setParameter( "name", "Thing" ).list();
assertEquals( 1, result.size() );
session.delete( boy );
transaction.commit();
}
finally {
if ( transaction.isActive() ) {
transaction.rollback();
}
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
boy.getNickNames().add( "Johnny" );
boy.getNickNames().add( "Thing" );
boy.getScorePerNickName().put( "Johnny", 3 );
boy.getScorePerNickName().put( "Thing", 5 );
int[] favNbrs = new int[4];
for ( int index = 0; index < favNbrs.length - 1; index++ ) {
favNbrs[index] = index * 3;
}
boy.setFavoriteNumbers( favNbrs );
boy.getCharacters().add( Character.GENTLE );
boy.getCharacters().add( Character.CRAFTY );
HashMap<String, FavoriteFood> foods = new HashMap<>();
foods.put( "breakfast", FavoriteFood.PIZZA );
foods.put( "lunch", FavoriteFood.KUNGPAOCHICKEN );
foods.put( "dinner", FavoriteFood.SUSHI );
boy.setFavoriteFood( foods );
session.persist( boy );
session.getTransaction().commit();
session.clear();
session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy.getNickNames() );
assertTrue( boy.getNickNames().contains( "Thing" ) );
assertNotNull( boy.getScorePerNickName() );
assertTrue( boy.getScorePerNickName().containsKey( "Thing" ) );
assertEquals( Integer.valueOf( 5 ), boy.getScorePerNickName().get( "Thing" ) );
assertNotNull( boy.getFavoriteNumbers() );
assertEquals( 3, boy.getFavoriteNumbers()[1] );
assertTrue( boy.getCharacters().contains( Character.CRAFTY ) );
assertTrue( boy.getFavoriteFood().get( "dinner" ).equals( FavoriteFood.SUSHI ) );
assertTrue( boy.getFavoriteFood().get( "lunch" ).equals( FavoriteFood.KUNGPAOCHICKEN ) );
assertTrue( boy.getFavoriteFood().get( "breakfast" ).equals( FavoriteFood.PIZZA ) );
List result = session.createQuery(
"select boy from Boy boy join boy.nickNames names where names = :name" )
.setParameter( "name", "Thing" ).list();
assertEquals( 1, result.size() );
session.delete( boy );
}
);
}
@Test
public void testCompositeElement(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
Toy toy = new Toy();
toy.setName( "Balloon" );
toy.setSerial( "serial001" );
toy.setBrand( new Brand() );
toy.getBrand().setName( "Bandai" );
boy.getFavoriteToys().add( toy );
session.persist( boy );
session.getTransaction().commit();
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
Toy toy = new Toy();
toy.setName( "Balloon" );
toy.setSerial( "serial001" );
toy.setBrand( new Brand() );
toy.getBrand().setName( "Bandai" );
boy.getFavoriteToys().add( toy );
session.persist( boy );
transaction.commit();
session.clear();
session.clear();
transaction = session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy );
assertNotNull( boy.getFavoriteToys() );
assertTrue( boy.getFavoriteToys().contains( toy ) );
Toy next = boy.getFavoriteToys().iterator().next();
assertEquals( boy, next.getOwner(), "@Parent is failing" );
session.delete( boy );
transaction.commit();
}
finally {
if ( transaction.isActive() ) {
transaction.rollback();
}
}
session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy );
assertNotNull( boy.getFavoriteToys() );
assertTrue( boy.getFavoriteToys().contains( toy ) );
Toy next = boy.getFavoriteToys().iterator().next();
assertEquals( boy, next.getOwner(), "@Parent is failing" );
session.delete( boy );
}
);
}
@Test
public void testAttributedJoin(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Country country = new Country();
country.setName( "Australia" );
session.persist( country );
Country country = new Country();
country.setName( "Australia" );
session.persist( country );
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
CountryAttitude attitude = new CountryAttitude();
// TODO: doesn't work
attitude.setBoy( boy );
attitude.setCountry( country );
attitude.setLikes( true );
boy.getCountryAttitudes().add( attitude );
session.persist( boy );
transaction.commit();
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
CountryAttitude attitude = new CountryAttitude();
// TODO: doesn't work
attitude.setBoy( boy );
attitude.setCountry( country );
attitude.setLikes( true );
boy.getCountryAttitudes().add( attitude );
session.persist( boy );
session.getTransaction().commit();
session.clear();
session.clear();
transaction = session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertTrue( boy.getCountryAttitudes().contains( attitude ) );
session.delete( boy );
session.delete( session.get( Country.class, country.getId() ) );
transaction.commit();
}
finally {
if ( transaction.isActive() ) {
transaction.rollback();
}
}
session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertTrue( boy.getCountryAttitudes().contains( attitude ) );
session.delete( boy );
session.delete( session.get( Country.class, country.getId() ) );
}
);
}
@ -214,113 +183,85 @@ public class DefaultNamingCollectionElementTest {
scope.getMetadataImplementor().getCollectionBinding( Boy.class.getName() + '.' + "favoriteNumbers" )
.getCollectionTable().getName()
);
scope.inSession(
scope.inTransaction(
session -> {
Transaction transaction = session.getTransaction();
try {
transaction.begin();
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
boy.getNickNames().add( "Johnny" );
boy.getNickNames().add( "Thing" );
boy.getScorePerNickName().put( "Johnny", 3 );
boy.getScorePerNickName().put( "Thing", 5 );
int[] favNbrs = new int[4];
for ( int index = 0; index < favNbrs.length - 1; index++ ) {
favNbrs[index] = index * 3;
}
boy.setFavoriteNumbers( favNbrs );
boy.getCharacters().add( Character.GENTLE );
boy.getCharacters().add( Character.CRAFTY );
session.persist( boy );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy.getNickNames() );
assertTrue( boy.getNickNames().contains( "Thing" ) );
assertNotNull( boy.getScorePerNickName() );
assertTrue( boy.getScorePerNickName().containsKey( "Thing" ) );
assertEquals( new Integer( 5 ), boy.getScorePerNickName().get( "Thing" ) );
assertNotNull( boy.getFavoriteNumbers() );
assertEquals( 3, boy.getFavoriteNumbers()[1] );
assertTrue( boy.getCharacters().contains( Character.CRAFTY ) );
List result = session.createQuery(
"select boy from Boy boy join boy.nickNames names where names = :name" )
.setParameter( "name", "Thing" ).list();
assertEquals( 1, result.size() );
session.delete( boy );
transaction.commit();
}
finally {
if ( transaction.isActive() ) {
transaction.rollback();
}
Boy boy = new Boy();
boy.setFirstName( "John" );
boy.setLastName( "Doe" );
boy.getNickNames().add( "Johnny" );
boy.getNickNames().add( "Thing" );
boy.getScorePerNickName().put( "Johnny", 3 );
boy.getScorePerNickName().put( "Thing", 5 );
int[] favNbrs = new int[4];
for ( int index = 0; index < favNbrs.length - 1; index++ ) {
favNbrs[index] = index * 3;
}
boy.setFavoriteNumbers( favNbrs );
boy.getCharacters().add( Character.GENTLE );
boy.getCharacters().add( Character.CRAFTY );
session.persist( boy );
session.getTransaction().commit();
session.clear();
session.beginTransaction();
boy = session.get( Boy.class, boy.getId() );
assertNotNull( boy.getNickNames() );
assertTrue( boy.getNickNames().contains( "Thing" ) );
assertNotNull( boy.getScorePerNickName() );
assertTrue( boy.getScorePerNickName().containsKey( "Thing" ) );
assertEquals( new Integer( 5 ), boy.getScorePerNickName().get( "Thing" ) );
assertNotNull( boy.getFavoriteNumbers() );
assertEquals( 3, boy.getFavoriteNumbers()[1] );
assertTrue( boy.getCharacters().contains( Character.CRAFTY ) );
List result = session.createQuery(
"select boy from Boy boy join boy.nickNames names where names = :name" )
.setParameter( "name", "Thing" ).list();
assertEquals( 1, result.size() );
session.delete( boy );
}
);
}
@Test
public void testFetchEagerAndFilter(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Transaction tx = session.beginTransaction();
try {
TestCourse test = new TestCourse();
TestCourse test = new TestCourse();
LocalizedString title = new LocalizedString( "title in english" );
title.getVariations().put( Locale.FRENCH.getLanguage(), "title en francais" );
test.setTitle( title );
session.save( test );
LocalizedString title = new LocalizedString( "title in english" );
title.getVariations().put( Locale.FRENCH.getLanguage(), "title en francais" );
test.setTitle( title );
session.save( test );
session.flush();
session.clear();
session.flush();
session.clear();
Filter filter = session.enableFilter( "selectedLocale" );
filter.setParameter( "param", "fr" );
Filter filter = session.enableFilter( "selectedLocale" );
filter.setParameter( "param", "fr" );
Query q = session.createQuery( "from TestCourse t" );
List l = q.list();
assertEquals( 1, l.size() );
Query q = session.createQuery( "from TestCourse t" );
List l = q.list();
assertEquals( 1, l.size() );
TestCourse t = session.get( TestCourse.class, test.getTestCourseId() );
assertEquals( 1, t.getTitle().getVariations().size() );
tx.rollback();
}
finally {
if ( tx.isActive() ) {
tx.rollback();
}
}
TestCourse t = session.get( TestCourse.class, test.getTestCourseId() );
assertEquals( 1, t.getTitle().getVariations().size() );
}
);
}
@Test
public void testMapKeyType(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Matrix m = new Matrix();
m.getMvalues().put( 1, 1.1f );
Transaction tx = session.beginTransaction();
try {
session.persist( m );
session.flush();
session.clear();
m = session.get( Matrix.class, m.getId() );
assertEquals( 1.1f, m.getMvalues().get( 1 ), 0.01f );
}
finally {
if ( tx.isActive() ) {
tx.rollback();
}
}
session.persist( m );
session.flush();
session.clear();
m = session.get( Matrix.class, m.getId() );
assertEquals( 1.1f, m.getMvalues().get( 1 ), 0.01f );
}
);
}

View File

@ -0,0 +1,147 @@
/*
* 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.collectionelement;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OrderBy;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@DomainModel(
annotatedClasses = {
org.hibernate.orm.test.annotations.collectionelement.OrderByColumnNameTest.Product.class,
org.hibernate.orm.test.annotations.collectionelement.OrderByColumnNameTest.Widgets.class,
org.hibernate.orm.test.annotations.collectionelement.OrderByColumnNameTest.Widget1.class,
org.hibernate.orm.test.annotations.collectionelement.OrderByColumnNameTest.Widget2.class,
}
)
@SessionFactory
public class OrderByColumnNameTest {
@Test
public void testOrderByName(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Product p = new Product();
HashSet<Widgets> set = new HashSet<>();
Widgets widget = new Widgets();
widget.setName( "hammer" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "axel" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "screwdriver" );
set.add( widget );
session.persist( widget );
p.setWidgets( set );
session.persist( p );
session.getTransaction().commit();
session.beginTransaction();
session.clear();
p = session.get( Product.class, p.getId() );
assertTrue( p.getWidgets().size() == 3, "has three Widgets" );
Iterator iter = p.getWidgets().iterator();
assertEquals( "axel", ( (Widgets) iter.next() ).getName() );
assertEquals( "hammer", ( (Widgets) iter.next() ).getName() );
assertEquals( "screwdriver", ( (Widgets) iter.next() ).getName() );
}
);
}
@Entity
public static class Product {
@Id
@GeneratedValue
private Integer id;
@ElementCollection
@OrderBy("name_1 ASC")
private Set<Widgets> widgets;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<Widgets> getWidgets() {
return widgets;
}
public void setWidgets(Set<Widgets> widgets) {
this.widgets = widgets;
}
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public static class Widgets {
private String name;
private int id;
public Widgets() {
}
@Column(name = "name_1")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
@Entity
public static class Widget1 extends org.hibernate.orm.test.annotations.collectionelement.Widgets {
private String name1;
}
@Entity
public static class Widget2 extends org.hibernate.orm.test.annotations.collectionelement.Widgets {
private String name2;
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.orm.test.annotations.collectionelement;
import java.util.HashSet;
import java.util.Iterator;
import org.hibernate.Transaction;
import org.hibernate.dialect.TeradataDialect;
import org.hibernate.testing.orm.junit.DomainModel;
@ -26,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
annotatedClasses = {
Products.class,
Widgets.class,
Widgets.Widget1.class,
Widgets.Widget2.class,
BugSystem.class
}
)
@ -34,49 +35,38 @@ public class OrderByTest {
@Test
public void testOrderByName(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Transaction tx = session.beginTransaction();
try {
Products p = new Products();
HashSet<Widgets> set = new HashSet<>();
Products p = new Products();
HashSet<Widgets> set = new HashSet<>();
Widgets widget = new Widgets();
widget.setName( "hammer" );
set.add( widget );
session.persist( widget );
Widgets widget = new Widgets();
widget.setName( "hammer" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "axel" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "axel" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "screwdriver" );
set.add( widget );
session.persist( widget );
widget = new Widgets();
widget.setName( "screwdriver" );
set.add( widget );
session.persist( widget );
p.setWidgets( set );
session.persist( p );
session.getTransaction().commit();
p.setWidgets( set );
session.persist( p );
tx.commit();
tx = session.beginTransaction();
session.clear();
p = session.get( Products.class, p.getId() );
assertTrue( p.getWidgets().size() == 3, "has three Widgets" );
Iterator iter = p.getWidgets().iterator();
assertEquals( "axel", ( (Widgets) iter.next() ).getName() );
assertEquals( "hammer", ( (Widgets) iter.next() ).getName() );
assertEquals( "screwdriver", ( (Widgets) iter.next() ).getName() );
tx.commit();
}
catch (Exception e) {
if ( tx.isActive() ) {
tx.rollback();
}
throw e;
}
session.beginTransaction();
session.clear();
p = session.get( Products.class, p.getId() );
assertTrue( p.getWidgets().size() == 3, "has three Widgets" );
Iterator iter = p.getWidgets().iterator();
assertEquals( "axel", ( (Widgets) iter.next() ).getName() );
assertEquals( "hammer", ( (Widgets) iter.next() ).getName() );
assertEquals( "screwdriver", ( (Widgets) iter.next() ).getName() );
}
);
}
@ -88,60 +78,50 @@ public class OrderByTest {
reason = "HHH-8190, uses Teradata reserved word - summary"
)
public void testOrderByWithDottedNotation(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Transaction tx = session.beginTransaction();
try {
BugSystem bs = new BugSystem();
HashSet<Bug> set = new HashSet<>();
BugSystem bs = new BugSystem();
HashSet<Bug> set = new HashSet<>();
Bug bug = new Bug();
bug.setDescription( "JPA-2 locking" );
bug.setSummary( "JPA-2 impl locking" );
Person p = new Person();
p.setFirstName( "Scott" );
p.setLastName( "Marlow" );
bug.setReportedBy( p );
set.add( bug );
Bug bug = new Bug();
bug.setDescription( "JPA-2 locking" );
bug.setSummary( "JPA-2 impl locking" );
Person p = new Person();
p.setFirstName( "Scott" );
p.setLastName( "Marlow" );
bug.setReportedBy( p );
set.add( bug );
bug = new Bug();
bug.setDescription( "JPA-2 annotations" );
bug.setSummary( "JPA-2 impl annotations" );
p = new Person();
p.setFirstName( "Emmanuel" );
p.setLastName( "Bernard" );
bug.setReportedBy( p );
set.add( bug );
bug = new Bug();
bug.setDescription( "JPA-2 annotations" );
bug.setSummary( "JPA-2 impl annotations" );
p = new Person();
p.setFirstName( "Emmanuel" );
p.setLastName( "Bernard" );
bug.setReportedBy( p );
set.add( bug );
bug = new Bug();
bug.setDescription( "Implement JPA-2 criteria" );
bug.setSummary( "JPA-2 impl criteria" );
p = new Person();
p.setFirstName( "Steve" );
p.setLastName( "Ebersole" );
bug.setReportedBy( p );
set.add( bug );
bug = new Bug();
bug.setDescription( "Implement JPA-2 criteria" );
bug.setSummary( "JPA-2 impl criteria" );
p = new Person();
p.setFirstName( "Steve" );
p.setLastName( "Ebersole" );
bug.setReportedBy( p );
set.add( bug );
bs.setBugs( set );
session.persist( bs );
tx.commit();
bs.setBugs( set );
session.persist( bs );
session.getTransaction().commit();
tx = session.beginTransaction();
session.clear();
bs = session.get( BugSystem.class, bs.getId() );
assertTrue( bs.getBugs().size() == 3, "has three bugs" );
Iterator iter = bs.getBugs().iterator();
assertEquals( "Emmanuel", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
assertEquals( "Steve", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
assertEquals( "Scott", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
tx.commit();
}
catch (Exception e) {
if ( tx.isActive() ) {
tx.rollback();
}
throw e;
}
session.beginTransaction();
session.clear();
bs = session.get( BugSystem.class, bs.getId() );
assertTrue( bs.getBugs().size() == 3, "has three bugs" );
Iterator iter = bs.getBugs().iterator();
assertEquals( "Emmanuel", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
assertEquals( "Steve", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
assertEquals( "Scott", ( (Bug) iter.next() ).getReportedBy().getFirstName() );
}
);

View File

@ -39,5 +39,4 @@ public class Products {
public void setWidgets(Set<Widgets> widgets) {
this.widgets = widgets;
}
}

View File

@ -5,11 +5,15 @@
* 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.collectionelement;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Widgets {
private String name;
private int id;
@ -18,6 +22,7 @@ public class Widgets {
}
@Column(name = "name_1")
public String getName() {
return name;
}
@ -36,4 +41,14 @@ public class Widgets {
this.id = id;
}
@Entity
public static class Widget1 extends Widgets{
private String name1;
}
@Entity
public static class Widget2 extends Widgets{
private String name2;
}
}

View File

@ -33,9 +33,8 @@ public class TestBasicOps {
public void testLoadAndStore(SessionFactoryScope scope) {
Query q = new Query( new Location( "first", Location.Type.COUNTY ) );
scope.inTransaction(
session -> {
session.save( q );
}
session ->
session.save( q )
);
scope.inTransaction(
@ -52,47 +51,37 @@ public class TestBasicOps {
@Test
@TestForIssue(jiraKey = "HHH-7072")
public void testEmbeddableWithNullables(SessionFactoryScope scope) {
scope.inSession(
scope.inTransaction(
session -> {
Query q = new Query( new Location( null, Location.Type.COMMUNE ) );
session.save( q );
session.getTransaction().commit();
session.clear();
Transaction transaction = session.beginTransaction();
try {
Query q = new Query( new Location( null, Location.Type.COMMUNE ) );
session.save( q );
transaction.commit();
session.clear();
q.getIncludedLocations().add( new Location( null, Location.Type.COUNTY ) );
session.update( q );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
q.getIncludedLocations().add( new Location( null, Location.Type.COUNTY ) );
session.update( q );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
q = (Query) session.get( Query.class, q.getId() );
transaction = session.beginTransaction();
q = session.get( Query.class, q.getId() );
// assertEquals( 2, q.getIncludedLocations().size() );
transaction.commit();
session.clear();
transaction.commit();
session.clear();
transaction = session.beginTransaction();
Iterator<Location> itr = q.getIncludedLocations().iterator();
itr.next();
itr.remove();
session.update( q );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
Iterator<Location> itr = q.getIncludedLocations().iterator();
itr.next();
itr.remove();
session.update( q );
transaction.commit();
session.clear();
transaction = session.beginTransaction();
q = (Query) session.get( Query.class, q.getId() );
assertEquals( 1, q.getIncludedLocations().size() );
session.delete( q );
transaction.commit();
}
catch (Exception e) {
if ( transaction.isActive() ) {
transaction.rollback();
}
throw e;
}
session.beginTransaction();
q = session.get( Query.class, q.getId() );
assertEquals( 1, q.getIncludedLocations().size() );
session.delete( q );
}
);
}