HHH-4528 - Applied patch (with minor cleanup)

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17849 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Hardy Ferentschik 2009-10-27 15:05:44 +00:00
parent f8fef6c6c1
commit 2176af1144
4 changed files with 308 additions and 2 deletions

View File

@ -127,6 +127,7 @@ import org.hibernate.annotations.GenericGenerators;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XAnnotatedElement;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XMethod;
import org.hibernate.annotations.common.reflection.XPackage;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.annotations.CollectionBinder;
@ -714,9 +715,10 @@ public final class AnnotationBinder {
//process idclass if any
Set<String> idProperties = new HashSet<String>();
IdClass idClass = null;
XClass current = null;
if ( !inheritanceState.hasParents ) {
//look for idClass
XClass current = inheritanceState.clazz;
current = inheritanceState.clazz;
InheritanceState state = inheritanceState;
do {
current = state.clazz;
@ -740,6 +742,9 @@ public final class AnnotationBinder {
PropertyData inferredData = new PropertyPreloadedData(
entityBinder.getPropertyAccessor(), "id", compositeClass
);
PropertyData baseInferredData = new PropertyPreloadedData(
entityBinder.getPropertyAccessor(), "id", current
);
HashMap<String, IdGenerator> localGenerators = new HashMap<String, IdGenerator>();
boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
entityBinder.setIgnoreIdAnnotations( true );
@ -747,6 +752,7 @@ public final class AnnotationBinder {
generatorType,
generator,
inferredData,
baseInferredData,
null,
propertyHolder,
localGenerators,
@ -762,6 +768,7 @@ public final class AnnotationBinder {
Component mapper = fillComponent(
propertyHolder,
inferredData,
baseInferredData,
propertyAnnotated,
propertyAccessor, false,
entityBinder,
@ -1941,6 +1948,17 @@ public final class AnnotationBinder {
EntityBinder entityBinder,
boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings
) {
return fillComponent(propertyHolder, inferredData, null, propertyAnnotated, propertyAccessor, isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper, inSecondPass, mappings);
}
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData, PropertyData baseInferredData,
boolean propertyAnnotated, String propertyAccessor, boolean isNullable,
EntityBinder entityBinder,
boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings
) {
/**
* inSecondPass can only be used to apply right away the second pass of a composite-element
* Because it's a value type, there is no bidirectional association, hence second pass
@ -1963,9 +1981,30 @@ public final class AnnotationBinder {
comp, subpath,
inferredData, propertyHolder, mappings
);
List<PropertyData> classElements = new ArrayList<PropertyData>();
XClass returnedClassOrElement = inferredData.getClassOrElement();
List<PropertyData> baseClassElements = null;
XClass baseReturnedClassOrElement;
PropertyHolder baseSubHolder;
if(baseInferredData != null)
{
baseSubHolder = PropertyHolderBuilder.buildPropertyHolder(
comp, subpath,
inferredData, propertyHolder, mappings
);
baseClassElements = new ArrayList<PropertyData>();
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
bindTypeDefs(baseReturnedClassOrElement, mappings);
addElementsOfAClass(
baseClassElements,
baseSubHolder,
propertyAnnotated,
propertyAccessor, baseReturnedClassOrElement, mappings
);
}
//embeddable elements can have type defs
bindTypeDefs(returnedClassOrElement, mappings);
addElementsOfAClass(
@ -1986,6 +2025,16 @@ public final class AnnotationBinder {
);
superClass = superClass.getSuperclass();
}
if(baseClassElements != null)
{
if(!hasIdClassAnnotations(inferredData.getPropertyClass()))
{
for(int i=0; i < classElements.size(); i++)
{
classElements.set(i, baseClassElements.get(i)); //this works since they are in the same order
}
}
}
for (PropertyData propertyAnnotatedElement : classElements) {
processElementAnnotations(
subHolder, isNullable ?
@ -2008,6 +2057,20 @@ public final class AnnotationBinder {
String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
boolean isIdentifierMapper, ExtendedMappings mappings
) {
bindId(generatorType, generatorName, inferredData, null, columns, propertyHolder, localGenerators, isComposite, isPropertyAnnotated, propertyAccessor, entityBinder, isEmbedded, isIdentifierMapper, mappings);
}
private static void bindId(
String generatorType, String generatorName, PropertyData inferredData,
PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
Map<String, IdGenerator> localGenerators,
boolean isComposite,
boolean isPropertyAnnotated,
String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
boolean isIdentifierMapper, ExtendedMappings mappings
) {
/*
* Fill simple value and property since and Id is a property
*/
@ -2025,7 +2088,7 @@ public final class AnnotationBinder {
SimpleValue id;
if ( isComposite ) {
id = fillComponent(
propertyHolder, inferredData, isPropertyAnnotated, propertyAccessor,
propertyHolder, inferredData, baseInferredData, isPropertyAnnotated, propertyAccessor,
false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings
);
Component componentId = (Component) id;
@ -2474,4 +2537,32 @@ public final class AnnotationBinder {
}
return inheritanceStatePerClass;
}
private static boolean hasIdClassAnnotations(XClass idClass)
{
if(idClass.getAnnotation(Embeddable.class) != null)
return true;
List<XProperty> properties = idClass.getDeclaredProperties( XClass.ACCESS_FIELD );
for ( XProperty property : properties ) {
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( OneToMany.class ) ||
property.isAnnotationPresent( ManyToOne.class ) || property.isAnnotationPresent( Id.class ) ||
property.isAnnotationPresent( GeneratedValue.class ) || property.isAnnotationPresent( OneToOne.class ) ||
property.isAnnotationPresent( ManyToMany.class )
) {
return true;
}
}
List<XMethod> methods = idClass.getDeclaredMethods();
for ( XMethod method : methods ) {
if ( method.isAnnotationPresent( Column.class ) || method.isAnnotationPresent( OneToMany.class ) ||
method.isAnnotationPresent( ManyToOne.class ) || method.isAnnotationPresent( Id.class ) ||
method.isAnnotationPresent( GeneratedValue.class ) || method.isAnnotationPresent( OneToOne.class ) ||
method.isAnnotationPresent( ManyToMany.class )
) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,84 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.test.annotations.idclass;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.NamedNativeQuery;
import javax.persistence.Table;
/**
* A DomainAdmin.
*
* @author <a href="mailto:stale.pedersen@jboss.org">Stale W. Pedersen</a>
*/
@Entity
@Table(name = "domainadmin")
@IdClass(DomainAdminId.class)
@NamedNativeQuery(name = "DomainAdmin.testQuery",
query = "select * from domainadmin da where da.domain_name = 'org'",
resultClass = org.hibernate.test.annotations.idclass.DomainAdmin.class)
public class DomainAdmin implements Serializable {
@Id
@Column(name = "domain_name")
private String domainName;
@Id
@Column(name = "admin_user")
private String adminUser;
@Column(name = "nick_name")
private String nickName;
public DomainAdmin() {
}
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public String getAdminUser() {
return adminUser;
}
public void setAdminUser(String adminUser) {
this.adminUser = adminUser;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
}

View File

@ -0,0 +1,73 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.test.annotations.idclass;
import java.io.Serializable;
/**
* A DomainAdminId.
*
* @author <a href="mailto:stale.pedersen@jboss.org">Stale W. Pedersen</a>
*/
@SuppressWarnings("serial")
public class DomainAdminId implements Serializable {
private String domainName;
private String adminUser;
public DomainAdminId() {
}
public DomainAdminId(String domainName, String adminUser) {
this.domainName = domainName;
this.adminUser = adminUser;
}
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public String getAdminUser() {
return adminUser;
}
public void setAdminUser(String adminUser) {
this.adminUser = adminUser;
}
@Override
public boolean equals(Object o) {
return ( ( o instanceof DomainAdminId ) && domainName.equals( ( ( DomainAdminId ) o ).getDomainName() ) &&
adminUser.equals( ( ( DomainAdminId ) o ).getAdminUser() ) );
}
@Override
public int hashCode() {
return ( domainName + adminUser ).hashCode();
}
}

View File

@ -0,0 +1,58 @@
// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.test.annotations.idclass;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.test.annotations.TestCase;
/**
* A IdClassTestCase.
*
* @author <a href="mailto:stale.pedersen@jboss.org">Stale W. Pedersen</a>
* @version $Revision: 1.1 $
*/
public class IdClassCompositePKTest extends TestCase {
public void testEntityMappningPropertiesAreNotIgnored() {
Session s = openSession();
Transaction tx = s.beginTransaction();
DomainAdmin da = new DomainAdmin();
da.setAdminUser( "admin" );
da.setDomainName( "org" );
s.persist( da );
Query q = s.getNamedQuery( "DomainAdmin.testQuery" );
assertEquals( 1, q.list().size() );
tx.rollback();
s.close();
}
protected Class[] getMappings() {
return new Class[] {
DomainAdmin.class
};
}
}