Fix issue with class used as IdClass and also embedded in another IdClass

This commit is contained in:
Andrea Boriero 2021-11-10 09:04:31 +01:00 committed by Christian Beikov
parent 07a314b663
commit b520752c8d
15 changed files with 146 additions and 99 deletions

View File

@ -67,6 +67,7 @@ import org.hibernate.sql.ast.tree.from.LazyTableGroup;
import org.hibernate.sql.ast.tree.from.MappedByTableGroup;
import org.hibernate.sql.ast.tree.from.PluralTableGroup;
import org.hibernate.sql.ast.tree.from.StandardTableGroup;
import org.hibernate.sql.ast.tree.from.StandardVirtualTableGroup;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
@ -79,6 +80,7 @@ import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.entity.EntityFetch;
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
import org.hibernate.sql.results.graph.entity.internal.EntityDelayedFetchImpl;
@ -995,6 +997,29 @@ public class ToOneAttributeMapping
tableGroup = tableGroupJoin.getJoinedGroup();
fromClauseAccess.registerTableGroup( fetchablePath, tableGroup );
}
else if ( fetchParent instanceof EmbeddableFetchImpl ) {
final TableGroup existingTableGroup = fromClauseAccess.findTableGroup(
fetchablePath
);
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
fetchablePath,
parentTableGroup,
resultVariable,
getJoinType( fetchablePath, parentTableGroup ),
true,
false,
creationState.getSqlAstCreationState()
);
final TableGroup joinedGroup = tableGroupJoin.getJoinedGroup();
if ( existingTableGroup == null || joinedGroup instanceof LazyTableGroup && existingTableGroup instanceof StandardVirtualTableGroup ) {
parentTableGroup.addTableGroupJoin( tableGroupJoin );
fromClauseAccess.registerTableGroup( fetchablePath, joinedGroup );
tableGroup = joinedGroup;
}
else {
tableGroup = existingTableGroup;
}
}
else {
tableGroup = fromClauseAccess.resolveTableGroup(
fetchablePath,
@ -1025,7 +1050,7 @@ public class ToOneAttributeMapping
);
}
}
return new EntityFetchJoinedImpl(
final EntityFetchJoinedImpl entityFetchJoined = new EntityFetchJoinedImpl(
fetchParent,
this,
tableGroup,
@ -1033,6 +1058,7 @@ public class ToOneAttributeMapping
fetchablePath,
creationState
);
return entityFetchJoined;
}
/*

View File

@ -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.derivedidentities.e2.a;
package org.hibernate.orm.test.annotations.derivedidentities.e2.a;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;

View File

@ -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.derivedidentities.e2.a;
package org.hibernate.orm.test.annotations.derivedidentities.e2.a;
import java.io.Serializable;
import jakarta.persistence.Embedded;

View File

@ -0,0 +1,71 @@
/*
* 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.derivedidentities.e2.a;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.orm.test.util.SchemaUtil;
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.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Emmanuel Bernard
*/
@DomainModel(
annotatedClasses = {
Employee.class,
Dependent.class
}
)
@SessionFactory
public class DerivedIdentityIdClassParentIdClassDepTest {
@Test
public void testManyToOne(SessionFactoryScope scope) {
final MetadataImplementor metadata = scope.getMetadataImplementor();
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK1", metadata ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK2", metadata ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", metadata ) );
assertTrue( !SchemaUtil.isColumnPresent( "Dependent", "firstName", metadata ) );
assertTrue( !SchemaUtil.isColumnPresent( "Dependent", "lastName", metadata ) );
Employee e = new Employee();
e.firstName = "Emmanuel";
e.lastName = "Bernard";
scope.inTransaction(
session -> {
session.persist( e );
Dependent d = new Dependent();
d.emp = e;
d.name = "Doggy";
session.persist( d );
session.flush();
session.clear();
DependentId dId = new DependentId();
EmployeeId eId = new EmployeeId();
dId.name = d.name;
dId.emp = eId;
eId.firstName = e.firstName;
eId.lastName = e.lastName;
d = session.get( Dependent.class, dId );
assertNotNull( d.emp );
assertEquals( e.firstName, d.emp.firstName );
session.delete( d );
session.delete( d.emp );
}
);
}
}

View File

@ -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.derivedidentities.e2.a;
package org.hibernate.orm.test.annotations.derivedidentities.e2.a;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;

View File

@ -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.derivedidentities.e2.a;
package org.hibernate.orm.test.annotations.derivedidentities.e2.a;
import java.io.Serializable;
/**

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import java.io.Serializable;
import java.math.BigDecimal;

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import java.io.Serializable;
import java.sql.PreparedStatement;

View File

@ -4,9 +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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import jakarta.persistence.PersistenceException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
@ -18,19 +17,22 @@ import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import org.hibernate.testing.orm.junit.BaseUnitTest;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.junit.jupiter.api.Test;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import jakarta.persistence.PersistenceException;
import static org.hibernate.testing.orm.junit.ExtraAssertions.assertTyping;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Chris Pheby
*/
@BaseUnitTest
@RequiresDialect(H2Dialect.class)
public class EmbeddableIntegratorTest extends BaseUnitTestCase {
public class EmbeddableIntegratorTest {
/**
* Throws a mapping exception because DollarValue is not mapped
@ -48,16 +50,22 @@ public class EmbeddableIntegratorTest extends BaseUnitTestCase {
sess.save( myInv );
sess.flush();
fail("A JDBCException expected");
fail( "A JDBCException expected" );
sess.clear();
Investor inv = (Investor) sess.get( Investor.class, 1L );
Investor inv = sess.get( Investor.class, 1L );
assertEquals( new BigDecimal( "100" ), inv.getInvestments().get( 0 ).getAmount().getAmount() );
}catch (PersistenceException e){
assertTyping(JDBCException.class, e.getCause());
}
catch (PersistenceException e) {
assertTyping( JDBCException.class, e.getCause() );
sess.getTransaction().rollback();
}
finally {
if ( sess.getTransaction().isActive() ) {
sess.getTransaction().rollback();
}
}
sess.close();
}
}
@ -68,6 +76,7 @@ public class EmbeddableIntegratorTest extends BaseUnitTestCase {
.registerTypeContributor( new InvestorTypeContributor() )
.setProperty( "hibernate.hbm2ddl.auto", "create-drop" )
.buildSessionFactory(); Session sess = sf.openSession()) {
try {
sess.getTransaction().begin();
Investor myInv = getInvestor();
myInv.setId( 2L );
@ -76,14 +85,20 @@ public class EmbeddableIntegratorTest extends BaseUnitTestCase {
sess.flush();
sess.clear();
Investor inv = (Investor) sess.get( Investor.class, 2L );
Investor inv = sess.get( Investor.class, 2L );
assertEquals( new BigDecimal( "100" ), inv.getInvestments().get( 0 ).getAmount().getAmount() );
}
finally {
if ( sess.getTransaction().isActive() ) {
sess.getTransaction().rollback();
}
}
}
}
private Investor getInvestor() {
Investor i = new Investor();
List<Investment> investments = new ArrayList<Investment>();
List<Investment> investments = new ArrayList<>();
Investment i1 = new Investment();
i1.setAmount( new DollarValue( new BigDecimal( "100" ) ) );
i1.setDate( new MyDate( new Date() ) );

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import java.util.ArrayList;
import java.util.List;

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.boot.model.TypeContributor;

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import java.io.Serializable;
import java.util.Date;

View File

@ -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.embeddables;
package org.hibernate.orm.test.annotations.embeddables;
import java.io.Serializable;
import java.sql.PreparedStatement;

View File

@ -1,65 +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.derivedidentities.e2.a;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.SchemaUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* @author Emmanuel Bernard
*/
public class DerivedIdentityIdClassParentIdClassDepTest extends BaseNonConfigCoreFunctionalTestCase {
@Test
public void testManytoOne() {
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK1", metadata() ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK2", metadata() ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", metadata() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", metadata() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", metadata() ) );
Employee e = new Employee();
e.firstName = "Emmanuel";
e.lastName = "Bernard";
Session s = openSession( );
s.getTransaction().begin();
s.persist( e );
Dependent d = new Dependent();
d.emp = e;
d.name = "Doggy";
s.persist( d );
s.flush();
s.clear();
DependentId dId = new DependentId();
EmployeeId eId = new EmployeeId();
dId.name = d.name;
dId.emp = eId;
eId.firstName = e.firstName;
eId.lastName = e.lastName;
d = (Dependent) s.get( Dependent.class, dId );
assertNotNull( d.emp );
assertEquals( e.firstName, d.emp.firstName );
s.delete( d );
s.delete( d.emp );
s.getTransaction().commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Employee.class,
Dependent.class
};
}
}