HHH-4805 take better care of generics.

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18566 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-01-15 18:47:54 +00:00
parent 9b38bca8ea
commit ecbe5dd854
6 changed files with 76 additions and 7 deletions

View File

@ -60,7 +60,7 @@
-->
<groupId>${project.groupId}</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>1.0.0-Beta-2</version>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>

View File

@ -27,6 +27,7 @@ import java.lang.reflect.Member;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.TypeVariable;
import java.util.Iterator;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
@ -733,12 +734,12 @@ public class AttributeFactory {
ParameterizedType signatureType = getSignatureType( member );
if ( keyPersistentAttributeType == null ) {
elementJavaType = (Class) signatureType.getActualTypeArguments()[0];
elementJavaType = getClassFromGenericArgument( signatureType.getActualTypeArguments()[0] );
keyJavaType = null;
}
else {
keyJavaType = (Class) signatureType.getActualTypeArguments()[0];
elementJavaType = (Class) signatureType.getActualTypeArguments()[1];
keyJavaType = getClassFromGenericArgument( signatureType.getActualTypeArguments()[0] );
elementJavaType = getClassFromGenericArgument( signatureType.getActualTypeArguments()[1] );
}
this.elementValueContext = new ValueContext() {
@ -804,6 +805,23 @@ public class AttributeFactory {
}
}
private Class<?> getClassFromGenericArgument(java.lang.reflect.Type type) {
Class<?> javaType;
Object unsafeElementType = type;
if ( unsafeElementType instanceof Class ) {
javaType = (Class) unsafeElementType;
}
else if ( unsafeElementType instanceof TypeVariable ) {
final java.lang.reflect.Type upperBound = ( ( TypeVariable ) unsafeElementType ).getBounds()[0];
javaType = getClassFromGenericArgument( upperBound );
}
else {
throw new AssertionFailure("Fail to process type argument in a generic declaration. Type: "
+ type.getClass() );
}
return javaType;
}
public ValueContext getElementValueContext() {
return elementValueContext;
}

View File

@ -0,0 +1,10 @@
package org.hibernate.ejb.test.metadata;
import javax.persistence.MappedSuperclass;
/**
* @author Emmanuel Bernard
*/
@MappedSuperclass
public class Being {
}

View File

@ -10,7 +10,7 @@ import javax.persistence.Table;
*/
@Entity
@Table(name="ejb_child")
public class Child {
public class Child extends Being {
private Integer id;
private String name;

View File

@ -274,16 +274,26 @@ public class MetadataTest extends TestCase {
assertNull( thing.getSupertype() );
}
public void testOneToManyJoinColumnUnidirectional() throws Exception {
public void testBackrefAndGenerics() throws Exception {
final EntityType<Parent> parent = factory.getMetamodel().entity( Parent.class );
assertNotNull( parent );
final SetAttribute<? super Parent, ?> children = parent.getSet( "children" );
assertNotNull( children );
assertEquals( 1, parent.getPluralAttributes().size() );
assertEquals( 3, parent.getAttributes().size() );
assertEquals( 4, parent.getAttributes().size() );
final EntityType<Child> child = factory.getMetamodel().entity( Child.class );
assertNotNull( child );
assertEquals( 2, child.getAttributes().size() );
final SingularAttribute<? super Parent, Parent.Relatives> attribute = parent.getSingularAttribute(
"siblings", Parent.Relatives.class
);
final EmbeddableType<Parent.Relatives> siblings = (EmbeddableType<Parent.Relatives>) attribute.getType();
assertNotNull(siblings);
final SetAttribute<? super Parent.Relatives, ?> siblingsCollection = siblings.getSet( "siblings" );
assertNotNull( siblingsCollection );
final Type<?> collectionElement = siblingsCollection.getElementType();
assertNotNull( collectionElement );
assertEquals( collectionElement, child );
}
private void ensureProperMember(Set<?> attributes) {

View File

@ -1,12 +1,15 @@
package org.hibernate.ejb.test.metadata;
import java.util.Set;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
/**
@ -15,9 +18,27 @@ import javax.persistence.Table;
@Entity
@Table(name="ejb_parent")
public class Parent {
@Embeddable
public static class Relatives<T extends Being> {
private Set<T> siblings;
@OneToMany
@JoinColumn(name="siblings_fk")
public Set<T> getSiblings() {
return siblings;
}
public void setSiblings(Set<T> siblings) {
this.siblings = siblings;
}
}
private Integer id;
private String name;
private Set<Child> children;
private Relatives<Child> siblings;
@Id
@GeneratedValue
@ -46,4 +67,14 @@ public class Parent {
public void setChildren(Set<Child> children) {
this.children = children;
}
//@Transient
@Embedded
public Relatives<Child> getSiblings() {
return siblings;
}
public void setSiblings(Relatives<Child> siblings) {
this.siblings = siblings;
}
}