Expose virtual id types in JPA metamodel

This commit is contained in:
Andrea Boriero 2021-11-11 10:04:30 +01:00 committed by Christian Beikov
parent 57f7e59e14
commit 971f58e335
14 changed files with 286 additions and 278 deletions

View File

@ -402,14 +402,27 @@ public class MetadataContext {
// Handle the actual id-attributes
final Component cidValue = (Component) persistentClass.getIdentifier();
final Iterator<Property> cidPropertyItr = cidValue.getPropertyIterator();
final Iterator<Property> cidPropertyItr;
final int propertySpan;
final EmbeddableTypeImpl<?> idClassType;
final Component identifierMapper = persistentClass.getIdentifierMapper();
if ( identifierMapper != null ) {
cidPropertyItr = identifierMapper.getPropertyIterator();
propertySpan = identifierMapper.getPropertySpan();
idClassType = applyIdClassMetadata( (Component) persistentClass.getIdentifier(), identifierMapper );
}
else {
cidPropertyItr = cidValue.getPropertyIterator();
propertySpan = cidValue.getPropertySpan();
idClassType = null;
}
assert cidValue.isEmbedded();
AbstractIdentifiableType idType = (AbstractIdentifiableType) entityTypesByEntityName.get( cidValue.getOwner().getEntityName() );
Set idAttributes = idType.getIdClassAttributesSafely();
if ( idAttributes == null ) {
idAttributes = new HashSet<>( cidValue.getPropertySpan() );
idAttributes = new HashSet<>( propertySpan );
while ( cidPropertyItr.hasNext() ) {
final Property cidSubProperty = cidPropertyItr.next();
final SingularPersistentAttribute<?, Object> cidSubAttr = attributeFactory.buildIdAttribute(
@ -421,15 +434,6 @@ public class MetadataContext {
}
}
// see if it also has an IdClass (identifier-mapper)
final Component idClass = persistentClass.getIdentifierMapper();
final EmbeddableTypeImpl<?> idClassType;
if ( idClass != null ) {
idClassType = applyIdClassMetadata( (Component) persistentClass.getIdentifier(), idClass );
}
else {
idClassType = null;
}
( ( AttributeContainer) identifiableType ).getInFlightAccess().applyNonAggregatedIdAttributes( idAttributes, idClassType );
}

View File

@ -6,7 +6,7 @@
*/
//$Id: Employee.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.lazyonetoone;
package org.hibernate.orm.test.lazyonetoone;
import java.util.ArrayList;
import java.util.Collection;

View File

@ -6,7 +6,7 @@
*/
//$Id: Employment.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.lazyonetoone;
package org.hibernate.orm.test.lazyonetoone;
import java.io.Serializable;
import java.util.Date;

View File

@ -0,0 +1,87 @@
/*
* 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.lazyonetoone;
import java.util.Date;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Gavin King
*/
@DomainModel(
xmlMappings = "org/hibernate/orm/test/lazyonetoone/Person.hbm.xml"
)
@SessionFactory
@ServiceRegistry(
settings = {
@Setting(name = Environment.MAX_FETCH_DEPTH, value = "2"),
@Setting(name = Environment.USE_SECOND_LEVEL_CACHE, value = "false")
}
)
public class LazyOneToOneTest {
@Test
public void testLazy(SessionFactoryScope scope) {
Person person = new Person( "Gavin" );
Employee e = new Employee( person );
Employment old = new Employment( e, "IFA" );
scope.inTransaction(
session -> {
Person p2 = new Person( "Emmanuel" );
new Employment( e, "JBoss" );
old.setEndDate( new Date() );
session.persist( person );
session.persist( p2 );
}
);
scope.inTransaction(
session -> {
Person p = (Person) session.createQuery( "from Person where name='Gavin'" ).uniqueResult();
//assertFalse( Hibernate.isPropertyInitialized(p, "employee") );
assertSame( p ,p.getEmployee().getPerson() );
assertTrue( Hibernate.isInitialized( p.getEmployee().getEmployments() ) );
assertEquals( 1, p.getEmployee().getEmployments().size() );
Person p2 = (Person) session.createQuery( "from Person where name='Emmanuel'" ).uniqueResult();
assertNull( p2.getEmployee() );
}
);
scope.inTransaction(
session -> {
Person p = session.get( Person.class, "Gavin" );
//assertFalse( Hibernate.isPropertyInitialized(p, "employee") );
assertSame( p.getEmployee().getPerson(), p );
assertTrue( Hibernate.isInitialized( p.getEmployee().getEmployments() ) );
assertEquals( p.getEmployee().getEmployments().size(), 1 );
Person p2 = session.get( Person.class, "Emmanuel" );
assertNull( p2.getEmployee() );
session.delete( p2 );
session.delete( old );
session.delete( p );
}
);
}
}

View File

@ -9,7 +9,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.lazyonetoone">
<hibernate-mapping package="org.hibernate.orm.test.lazyonetoone">
<class name="Person">
<id name="name"/>

View File

@ -6,7 +6,7 @@
*/
//$Id: Person.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.lazyonetoone;
package org.hibernate.orm.test.lazyonetoone;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: Address.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.typedonetoone;
package org.hibernate.orm.test.typedonetoone;
import java.io.Serializable;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: AddressId.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.typedonetoone;
package org.hibernate.orm.test.typedonetoone;
import java.io.Serializable;
/**

View File

@ -19,7 +19,7 @@
-->
<hibernate-mapping package="org.hibernate.test.typedonetoone">
<hibernate-mapping package="org.hibernate.orm.test.typedonetoone">
<class name="Customer">

View File

@ -6,7 +6,7 @@
*/
//$Id: Customer.java 5686 2005-02-12 07:27:32Z steveebersole $
package org.hibernate.test.typedonetoone;
package org.hibernate.orm.test.typedonetoone;
import java.io.Serializable;
/**

View File

@ -0,0 +1,110 @@
/*
* 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.typedonetoone;
import java.util.List;
import org.hibernate.Hibernate;
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.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Gavin King
*/
@DomainModel(
xmlMappings = "org/hibernate/orm/test/typedonetoone/Customer.hbm.xml"
)
@SessionFactory
public class TypedOneToOneTest {
@Test
public void testCreateQuery(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Customer cust = new Customer();
cust.setCustomerId( "abc123" );
cust.setName( "Matt" );
Address ship = new Address();
ship.setStreet( "peachtree rd" );
ship.setState( "GA" );
ship.setCity( "ATL" );
ship.setZip( "30326" );
ship.setAddressId( new AddressId( "SHIPPING", "abc123" ) );
ship.setCustomer( cust );
Address bill = new Address();
bill.setStreet( "peachtree rd" );
bill.setState( "GA" );
bill.setCity( "ATL" );
bill.setZip( "30326" );
bill.setAddressId( new AddressId( "BILLING", "abc123" ) );
bill.setCustomer( cust );
cust.setBillingAddress( bill );
cust.setShippingAddress( ship );
session.persist( cust );
}
);
scope.inTransaction(
session -> {
List<Customer> results = session.createQuery(
"from Customer cust left join fetch cust.billingAddress where cust.customerId='abc123'" )
.list();
//List results = s.createQuery("from Customer cust left join fetch cust.billingAddress left join fetch cust.shippingAddress").list();
Customer cust = results.get( 0 );
assertTrue( Hibernate.isInitialized( cust.getShippingAddress() ) );
assertTrue( Hibernate.isInitialized( cust.getBillingAddress() ) );
assertEquals( "30326", cust.getBillingAddress().getZip() );
assertEquals( "30326", cust.getShippingAddress().getZip() );
assertEquals( "BILLING", cust.getBillingAddress().getAddressId().getType() );
assertEquals( "SHIPPING", cust.getShippingAddress().getAddressId().getType() );
session.delete( cust );
}
);
}
@Test
public void testCreateQueryNull(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Customer cust = new Customer();
cust.setCustomerId( "xyz123" );
cust.setName( "Matt" );
session.persist( cust );
}
);
scope.inTransaction(
session -> {
List<Customer> results = session.createQuery(
"from Customer cust left join fetch cust.billingAddress where cust.customerId='xyz123'" )
.list();
//List results = s.createQuery("from Customer cust left join fetch cust.billingAddress left join fetch cust.shippingAddress").list();
Customer cust = results.get( 0 );
assertNull( cust.getShippingAddress() );
assertNull( cust.getBillingAddress() );
session.delete( cust );
}
);
}
}

View File

@ -8,73 +8,79 @@ package org.hibernate.test.annotations.derivedidentities.e1.a;
import java.util.List;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.orm.test.util.SchemaUtil;
import org.junit.Test;
import org.hibernate.query.Query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
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.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Emmanuel Bernard
*/
public class DerivedIdentitySimpleParentIdClassDepTest extends BaseNonConfigCoreFunctionalTestCase {
@Test
public void testManyToOne() throws Exception {
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_empId", metadata() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "emp", metadata() ) );
Session s = openSession();
s.getTransaction().begin();
Employee e = new Employee( 1L, "Emmanuel", "Manu" );
Dependent d = new Dependent( "Doggy", e );
s.persist( d );
s.persist( e );
s.getTransaction().commit();
s.close();
s = openSession();
s.getTransaction().begin();
DependentId dId = new DependentId( d.getName(), d.getEmp().empId );
d = (Dependent) s.get( Dependent.class, dId );
assertEquals( e.empId, d.getEmp().empId );
assertEquals( e.empName, d.getEmp().empName );
assertEquals( e.nickname, d.getEmp().nickname );
s.delete( d );
s.delete( d.getEmp() );
s.getTransaction().commit();
s.close();
}
@Test
public void testQueryNewEntityInPC() throws Exception {
Session s = openSession();
s.getTransaction().begin();
Employee e = new Employee( 1L, "Paula", "P" );
Dependent d = new Dependent( "LittleP", e );
d.setEmp(e);
s.persist( d );
s.persist( e );
// find the entity added above
Query query = s.createQuery("Select d from Dependent d where d.name='LittleP' and d.emp.empName='Paula'");
List depList = query.list();
assertEquals( 1, depList.size() );
Object newDependent = depList.get(0);
assertSame( d, newDependent );
s.getTransaction().rollback();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
@DomainModel(
annotatedClasses = {
Dependent.class,
Employee.class
};
}
)
@SessionFactory
public class DerivedIdentitySimpleParentIdClassDepTest {
@Test
public void testManyToOne(SessionFactoryScope scope) {
final MetadataImplementor metadata = scope.getMetadataImplementor();
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_empId", metadata ) );
assertTrue( !SchemaUtil.isColumnPresent( "Dependent", "emp", metadata ) );
Employee e = new Employee( 1L, "Emmanuel", "Manu" );
Dependent dependent = new Dependent( "Doggy", e );
scope.inTransaction(
session -> {
session.persist( dependent );
session.persist( e );
}
);
scope.inTransaction(
session -> {
DependentId dId = new DependentId( dependent.getName(), dependent.getEmp().empId );
Dependent d = session.get( Dependent.class, dId );
assertEquals( e.empId, d.getEmp().empId );
assertEquals( e.empName, d.getEmp().empName );
assertEquals( e.nickname, d.getEmp().nickname );
session.delete( d );
session.delete( d.getEmp() );
}
);
}
@Test
public void testQueryNewEntityInPC(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Employee e = new Employee( 1L, "Paula", "P" );
Dependent d = new Dependent( "LittleP", e );
d.setEmp( e );
session.persist( d );
session.persist( e );
// find the entity added above
Query query = session.createQuery(
"Select d from Dependent d where d.name='LittleP' and d.emp.empName='Paula'" );
List depList = query.list();
assertEquals( 1, depList.size() );
Object newDependent = depList.get( 0 );
assertSame( d, newDependent );
session.delete( d );
session.delete( d.getEmp() );
}
);
}
}

View File

@ -1,95 +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.lazyonetoone;
import java.util.Date;
import org.junit.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.testing.Skip;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* @author Gavin King
*/
@Skip(
condition = LazyOneToOneTest.DomainClassesInstrumentedMatcher.class,
message = "Test domain classes were not instrumented"
)
public class LazyOneToOneTest extends BaseCoreFunctionalTestCase {
public String[] getMappings() {
return new String[] { "lazyonetoone/Person.hbm.xml" };
}
public void configure(Configuration cfg) {
cfg.setProperty(Environment.MAX_FETCH_DEPTH, "2");
cfg.setProperty(Environment.USE_SECOND_LEVEL_CACHE, "false");
}
@Test
public void testLazy() throws Exception {
Session s = openSession();
Transaction t = s.beginTransaction();
Person p = new Person("Gavin");
Person p2 = new Person("Emmanuel");
Employee e = new Employee(p);
new Employment(e, "JBoss");
Employment old = new Employment(e, "IFA");
old.setEndDate( new Date() );
s.persist(p);
s.persist(p2);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
p = (Person) s.createQuery("from Person where name='Gavin'").uniqueResult();
//assertFalse( Hibernate.isPropertyInitialized(p, "employee") );
assertSame( p.getEmployee().getPerson(), p );
assertTrue( Hibernate.isInitialized( p.getEmployee().getEmployments() ) );
assertEquals( p.getEmployee().getEmployments().size(), 1 );
p2 = (Person) s.createQuery("from Person where name='Emmanuel'").uniqueResult();
assertNull( p2.getEmployee() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
p = (Person) s.get(Person.class, "Gavin");
//assertFalse( Hibernate.isPropertyInitialized(p, "employee") );
assertSame( p.getEmployee().getPerson(), p );
assertTrue( Hibernate.isInitialized( p.getEmployee().getEmployments() ) );
assertEquals( p.getEmployee().getEmployments().size(), 1 );
p2 = (Person) s.get(Person.class, "Emmanuel");
assertNull( p2.getEmployee() );
s.delete(p2);
s.delete(old);
s.delete(p);
t.commit();
s.close();
}
public static class DomainClassesInstrumentedMatcher implements Skip.Matcher {
@Override
public boolean isMatch() {
// we match (to skip) when the classes are *not* instrumented...
return ! PersistentAttributeInterceptable.class.isAssignableFrom( Person.class );
}
}
}

View File

@ -1,104 +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.typedonetoone;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Gavin King
*/
public class TypedOneToOneTest extends BaseCoreFunctionalTestCase {
@Override
public String[] getMappings() {
return new String[] { "typedonetoone/Customer.hbm.xml" };
}
@Test
public void testCreateQuery() {
Customer cust = new Customer();
cust.setCustomerId("abc123");
cust.setName("Matt");
Address ship = new Address();
ship.setStreet("peachtree rd");
ship.setState("GA");
ship.setCity("ATL");
ship.setZip("30326");
ship.setAddressId( new AddressId("SHIPPING", "abc123") );
ship.setCustomer(cust);
Address bill = new Address();
bill.setStreet("peachtree rd");
bill.setState("GA");
bill.setCity("ATL");
bill.setZip("30326");
bill.setAddressId( new AddressId("BILLING", "abc123") );
bill.setCustomer(cust);
cust.setBillingAddress(bill);
cust.setShippingAddress(ship);
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(cust);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
List results = s.createQuery("from Customer cust left join fetch cust.billingAddress where cust.customerId='abc123'").list();
//List results = s.createQuery("from Customer cust left join fetch cust.billingAddress left join fetch cust.shippingAddress").list();
cust = (Customer) results.get(0);
assertTrue( Hibernate.isInitialized( cust.getShippingAddress() ) );
assertTrue( Hibernate.isInitialized( cust.getBillingAddress() ) );
assertEquals( "30326", cust.getBillingAddress().getZip() );
assertEquals( "30326", cust.getShippingAddress().getZip() );
assertEquals( "BILLING", cust.getBillingAddress().getAddressId().getType() );
assertEquals( "SHIPPING", cust.getShippingAddress().getAddressId().getType() );
s.delete( cust );
t.commit();
s.close();
}
@Test
public void testCreateQueryNull() {
Customer cust = new Customer();
cust.setCustomerId("xyz123");
cust.setName("Matt");
Session s = openSession();
Transaction t = s.beginTransaction();
s.persist(cust);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
List results = s.createQuery("from Customer cust left join fetch cust.billingAddress where cust.customerId='xyz123'").list();
//List results = s.createQuery("from Customer cust left join fetch cust.billingAddress left join fetch cust.shippingAddress").list();
cust = (Customer) results.get(0);
assertNull( cust.getShippingAddress() );
assertNull( cust.getBillingAddress() );
s.delete(cust);
t.commit();
s.close();
}
}