HHH-4848 Add more of the spec test for derived identity and @IdClass. Missing example 5.a and example 6.a (bug at the moment)
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18702 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
ab4f51dce5
commit
5ad11ba2a1
|
@ -1712,19 +1712,31 @@ public final class
|
|||
//Either a regular property or a basic @Id or @EmbeddedId while not ignoring id annotations
|
||||
else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
|
||||
//define whether the type is a component or not
|
||||
boolean isComponent;
|
||||
isComponent = property.isAnnotationPresent( Embedded.class )
|
||||
|| property.isAnnotationPresent( EmbeddedId.class )
|
||||
|| returnedClass.isAnnotationPresent( Embeddable.class );
|
||||
|
||||
//FIXME do the overrideColumnFromMapsIdProperty here and force the idclass type to look like an @embedded
|
||||
boolean isComponent = false;
|
||||
|
||||
//Overrides from @MapsId if needed
|
||||
boolean isOverridden = false;
|
||||
if ( isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass() ) {
|
||||
Ejb3Column[] oldColumns = columns;
|
||||
columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty(isId);
|
||||
isOverridden = oldColumns != columns;
|
||||
//the associated entity could be using an @IdClass making the overridden property a component
|
||||
final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), mappings );
|
||||
if (overridingProperty != null) {
|
||||
isOverridden = true;
|
||||
final InheritanceState state = inheritanceStatePerClass.get( overridingProperty.getClassOrElement() );
|
||||
if (state != null) {
|
||||
isComponent = isComponent || state.hasIdClassOrEmbeddedId();
|
||||
}
|
||||
//Get the new column
|
||||
columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty(isId);
|
||||
}
|
||||
}
|
||||
|
||||
isComponent = isComponent
|
||||
|| property.isAnnotationPresent( Embedded.class )
|
||||
|| property.isAnnotationPresent( EmbeddedId.class )
|
||||
|| returnedClass.isAnnotationPresent( Embeddable.class );
|
||||
|
||||
|
||||
if ( isComponent ) {
|
||||
String referencedEntityName = null;
|
||||
if (isOverridden) {
|
||||
|
@ -2085,19 +2097,22 @@ public final class
|
|||
for ( int i = 0; i < classElements.size(); i++ ) {
|
||||
final PropertyData idClassPropertyData = classElements.get( i );
|
||||
final PropertyData entityPropertyData = orderedBaseClassElements.get( idClassPropertyData.getPropertyName() );
|
||||
if ( propertyHolder.isInIdClass() ) {
|
||||
if ( entityPropertyData.getProperty().isAnnotationPresent( ManyToOne.class )
|
||||
|| entityPropertyData.getProperty().isAnnotationPresent( OneToOne.class ) ) {
|
||||
//don't replace here as we need to use the actual original return type
|
||||
//the annotation overriding will be dealt with by a mechanism similar to @MapsId
|
||||
//FIXME
|
||||
if ( entityPropertyData != null ) {
|
||||
if ( propertyHolder.isInIdClass() ) {
|
||||
if ( entityPropertyData.getProperty().isAnnotationPresent( ManyToOne.class )
|
||||
|| entityPropertyData.getProperty().isAnnotationPresent( OneToOne.class ) ) {
|
||||
//don't replace here as we need to use the actual original return type
|
||||
//the annotation overriding will be dealt with by a mechanism similar to @MapsId
|
||||
}
|
||||
else {
|
||||
classElements.set( i, entityPropertyData ); //this works since they are in the same order
|
||||
}
|
||||
}
|
||||
else {
|
||||
classElements.set( i, entityPropertyData ); //this works since they are in the same order
|
||||
}
|
||||
}
|
||||
else {
|
||||
classElements.set( i, entityPropertyData ); //this works since they are in the same order
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,11 +183,11 @@ class ColumnsBuilder {
|
|||
|
||||
Ejb3Column[] overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
|
||||
Ejb3Column[] result = columns;
|
||||
final PropertyData annotatedWithMapsId = BinderHelper.getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), mappings );
|
||||
if ( annotatedWithMapsId != null ) {
|
||||
result = buildExplicitJoinColumns( annotatedWithMapsId.getProperty(), annotatedWithMapsId );
|
||||
final PropertyData overridingProperty = BinderHelper.getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder, property.getName(), mappings );
|
||||
if ( overridingProperty != null ) {
|
||||
result = buildExplicitJoinColumns( overridingProperty.getProperty(), overridingProperty );
|
||||
if (result == null) {
|
||||
result = buildDefaultJoinColumnsForXToOne( annotatedWithMapsId.getProperty(), annotatedWithMapsId);
|
||||
result = buildDefaultJoinColumnsForXToOne( overridingProperty.getProperty(), overridingProperty);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -67,6 +67,7 @@ public class InheritanceState {
|
|||
private ExtendedMappings mappings;
|
||||
private AccessType accessType;
|
||||
private ElementsToProcess elementsToProcess;
|
||||
private Boolean hasIdClassOrEmbeddedId;
|
||||
|
||||
public InheritanceState(XClass clazz,
|
||||
Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||
|
@ -167,21 +168,6 @@ public class InheritanceState {
|
|||
isEmbeddableSuperclass = embeddableSuperclass;
|
||||
}
|
||||
|
||||
public XClass getIdentifierTypeIfComponent() {
|
||||
final ReflectionManager reflectionManager = mappings.getReflectionManager();
|
||||
if ( reflectionManager.equals( identifierType, void.class ) ) {
|
||||
IdClass idClass = clazz.getAnnotation( IdClass.class );
|
||||
if (idClass != null) {
|
||||
identifierType = reflectionManager.toXClass( idClass.value() );
|
||||
}
|
||||
else {
|
||||
//find @EmbeddedId
|
||||
getElementsToProcess();
|
||||
}
|
||||
}
|
||||
return identifierType;
|
||||
}
|
||||
|
||||
void postProcess(PersistentClass persistenceClass, EntityBinder entityBinder) {
|
||||
//make sure we run elements to process
|
||||
getElementsToProcess();
|
||||
|
@ -204,14 +190,32 @@ public class InheritanceState {
|
|||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean hasIdClassOrEmbeddedId() {
|
||||
if (hasIdClassOrEmbeddedId == null) {
|
||||
hasIdClassOrEmbeddedId = false;
|
||||
if ( getClassWithIdClass( true ) != null ) {
|
||||
hasIdClassOrEmbeddedId = true;
|
||||
}
|
||||
else {
|
||||
final ElementsToProcess process = getElementsToProcess();
|
||||
for(PropertyData property : process.getElements() ) {
|
||||
if ( property.getProperty().isAnnotationPresent( EmbeddedId.class ) ) {
|
||||
hasIdClassOrEmbeddedId = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasIdClassOrEmbeddedId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
|
||||
* Change EntityBinder by side effect
|
||||
*/
|
||||
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
|
||||
* Change EntityBinder by side effect
|
||||
*/
|
||||
public ElementsToProcess getElementsToProcess() {
|
||||
if (elementsToProcess == null) {
|
||||
InheritanceState inheritanceState = inheritanceStatePerClass.get( clazz );
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e2.a;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinColumns;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(DependentId.class)
|
||||
public class Dependent {
|
||||
@Id
|
||||
String name;
|
||||
|
||||
@Id @ManyToOne
|
||||
@JoinColumns({
|
||||
@JoinColumn(name="FK1", referencedColumnName="firstName"),
|
||||
@JoinColumn(name="FK2", referencedColumnName="lastName")
|
||||
})
|
||||
Employee emp;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e2.a;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DependentId implements Serializable {
|
||||
String name; // matches name of @Id attribute
|
||||
@Embedded
|
||||
EmployeeId emp; //matches name of attribute and type of Employee PK
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e2.a;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.test.annotations.TestCase;
|
||||
import org.hibernate.test.util.SchemaUtil;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DerivedIdentityIdClassParentIdClassDepTest extends TestCase {
|
||||
|
||||
public void testManytoOne() {
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK1", getCfg() ) );
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK2", getCfg() ) );
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", getCfg() ) );
|
||||
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", getCfg() ) );
|
||||
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", getCfg() ) );
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e2.a;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(EmployeeId.class)
|
||||
public class Employee {
|
||||
@Id String firstName;
|
||||
@Id String lastName;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e2.a;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class EmployeeId implements Serializable {
|
||||
String firstName;
|
||||
String lastName;
|
||||
}
|
|
@ -25,9 +25,6 @@ public class DerivedIdentityIdClassParentEmbeddedIdDepTest extends TestCase {
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
// d.id.empPK = new EmployeeId(); //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.firstName = e.firstName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.lastName = e.lastName; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -6,7 +6,6 @@ import javax.persistence.Embeddable;
|
|||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Embeddable
|
||||
public class EmployeeId implements Serializable {
|
||||
String firstName;
|
||||
String lastName;
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e3.a;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinColumns;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(DependentId.class)
|
||||
public class Dependent {
|
||||
@Id
|
||||
@Column(name = "dep_name")
|
||||
String name; // default column name is overridden
|
||||
|
||||
@Id
|
||||
@JoinColumns({
|
||||
@JoinColumn(name = "FK1", referencedColumnName = "firstName"),
|
||||
@JoinColumn(name = "FK2", referencedColumnName = "lastName")
|
||||
})
|
||||
@ManyToOne
|
||||
Employee emp;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e3.a;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DependentId implements Serializable {
|
||||
String name; // matches name of @Id attribute
|
||||
EmployeeId emp; // matches name of @Id attribute and type of embedded id of Employee
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e3.a;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.test.annotations.TestCase;
|
||||
import org.hibernate.test.util.SchemaUtil;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DerivedIdentityEmbeddedIdParentIdClassTest extends TestCase {
|
||||
public void testManyToOne() throws Exception {
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK1", getCfg() ) );
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK2", getCfg() ) );
|
||||
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "dep_name", getCfg() ) );
|
||||
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", getCfg() ) );
|
||||
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", getCfg() ) );
|
||||
Employee e = new Employee();
|
||||
e.empId = new EmployeeId();
|
||||
e.empId.firstName = "Emmanuel";
|
||||
e.empId.lastName = "Bernard";
|
||||
Session s = openSession( );
|
||||
s.getTransaction().begin();
|
||||
s.persist( e );
|
||||
Dependent d = new Dependent();
|
||||
d.emp = e;
|
||||
d.name = "Doggy";
|
||||
DependentId dId = new DependentId();
|
||||
dId.emp = new EmployeeId();
|
||||
dId.emp.firstName = e.empId.firstName;
|
||||
dId.emp.lastName = e.empId.lastName;
|
||||
dId.name = d.name;
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
d = (Dependent) s.get( Dependent.class, dId );
|
||||
assertNotNull( d.emp );
|
||||
assertEquals( e.empId.firstName, d.emp.empId.firstName );
|
||||
s.delete( d );
|
||||
s.delete( d.emp );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Dependent.class,
|
||||
Employee.class
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e3.a;
|
||||
|
||||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Employee {
|
||||
@EmbeddedId
|
||||
EmployeeId empId;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e3.a;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class EmployeeId implements Serializable{
|
||||
String firstName;
|
||||
String lastName;
|
||||
}
|
|
@ -25,9 +25,6 @@ public class DerivedIdentityEmbeddedIdParentEmbeddedIdDepTest extends TestCase {
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
// d.id.empPK = new EmployeeId();
|
||||
// d.id.empPK.firstName = e.empId.firstName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.lastName = e.empId.lastName; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -3,13 +3,14 @@ package org.hibernate.test.annotations.derivedidentities.e5.b;
|
|||
import java.util.Date;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.junit.FailureExpected;
|
||||
import org.hibernate.test.annotations.TestCase;
|
||||
import org.hibernate.test.util.SchemaUtil;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DerivedIdentityIdClassParentSameIdTypeDepTest extends TestCase {
|
||||
public class DerivedIdentityIdClassParentSameIdTypeEmbeddedIdDepTest extends TestCase {
|
||||
|
||||
public void testOneToOneExplicitJoinColumn() throws Exception {
|
||||
assertTrue( SchemaUtil.isColumnPresent( "MedicalHistory", "FK1", getCfg() ) );
|
||||
|
@ -22,9 +23,6 @@ public class DerivedIdentityIdClassParentSameIdTypeDepTest extends TestCase {
|
|||
s.getTransaction().begin();
|
||||
s.persist( e );
|
||||
MedicalHistory d = new MedicalHistory();
|
||||
// d.id = new PersonId(); //FIXME not needed when foreign is enabled
|
||||
// d.id.firstName = "Emmanuel"; //FIXME not needed when foreign is enabled
|
||||
// d.id.lastName = "Bernard"; //FIXME not needed when foreign is enabled
|
||||
d.patient = e;
|
||||
s.persist( d );
|
||||
s.flush();
|
|
@ -7,7 +7,7 @@ import org.hibernate.test.util.SchemaUtil;
|
|||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DerivedIdentityEmbeddedIdParentSameIdTypeDepTest extends TestCase {
|
||||
public class DerivedIdentityEmbeddedIdParentSameIdTypeEmbeddedIdDepTest extends TestCase {
|
||||
|
||||
public void testOneToOneExplicitJoinColumn() throws Exception {
|
||||
assertTrue( SchemaUtil.isColumnPresent( "MedicalHistory", "FK1", getCfg() ) );
|
|
@ -500,7 +500,7 @@
|
|||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.0-CR-1</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- Set the version of the hibernate-commons-annotations to be used throughout the the project -->
|
||||
<dependency>
|
||||
|
|
Loading…
Reference in New Issue