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:
Emmanuel Bernard 2010-02-05 14:37:34 +00:00
parent ab4f51dce5
commit 5ad11ba2a1
19 changed files with 294 additions and 52 deletions

View File

@ -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
}
}
}
}

View File

@ -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;

View File

@ -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 );

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
};
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();

View File

@ -6,7 +6,6 @@ import javax.persistence.Embeddable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
public class EmployeeId implements Serializable {
String firstName;
String lastName;

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
};
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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();

View File

@ -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() ) );

View File

@ -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>