From d74037756e75b438a69b64210be051a97e5e5d75 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 26 Oct 2009 17:04:59 +0000 Subject: [PATCH] HHH-4202 - Implement JPA 2.0 metamodel APIs git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17843 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../property/BackrefPropertyAccessor.java | 17 ++- .../property/BasicPropertyAccessor.java | 32 ++++- .../property/ChainedPropertyAccessor.java | 9 +- .../property/DirectPropertyAccessor.java | 47 ++++++- .../org/hibernate/property/Dom4jAccessor.java | 75 +++++++---- .../property/EmbeddedPropertyAccessor.java | 51 +++++-- .../java/org/hibernate/property/Getter.java | 30 ++++- .../property/IndexPropertyAccessor.java | 48 +++++-- .../org/hibernate/property/MapAccessor.java | 51 +++++-- .../org/hibernate/property/NoopAccessor.java | 57 ++++++-- .../hibernate/property/PropertyAccessor.java | 25 +++- .../property/PropertyAccessorFactory.java | 9 +- .../java/org/hibernate/property/Setter.java | 9 +- .../java/org/hibernate/property/package.html | 9 +- .../java/org/hibernate/tuple/Tuplizer.java | 21 +-- .../component/AbstractComponentTuplizer.java | 13 +- .../component/PojoComponentTuplizer.java | 1 - .../tuple/entity/AbstractEntityTuplizer.java | 18 ++- .../tuple/entity/EntityTuplizer.java | 15 +++ .../tuple/entity/PojoEntityTuplizer.java | 1 - .../org/hibernate/type/ComponentType.java | 16 +++ .../ejb/EntityManagerFactoryImpl.java | 3 +- .../metamodel/AbstractIdentifiableType.java | 28 ++-- .../ejb/metamodel/AttributeFactory.java | 127 ++++++++++++++---- .../ejb/metamodel/EmbeddableTypeImpl.java | 18 ++- .../ejb/metamodel/MetadataContext.java | 10 ++ .../ejb/metamodel/MetamodelImpl.java | 34 +++-- .../ejb/test/metadata/MetadataTest.java | 10 ++ 28 files changed, 600 insertions(+), 184 deletions(-) diff --git a/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java b/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java index 8347d4c6f3..8492773151 100755 --- a/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.io.Serializable; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.engine.SessionFactoryImplementor; @@ -140,6 +140,13 @@ public class BackrefPropertyAccessor implements PropertyAccessor { } } + /** + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + /** * {@inheritDoc} */ diff --git a/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java b/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java index dfdd39d44e..17be25bbcc 100644 --- a/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.beans.Introspector; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.slf4j.Logger; @@ -164,6 +164,9 @@ public class BasicPropertyAccessor implements PropertyAccessor { this.propertyName=propertyName; } + /** + * {@inheritDoc} + */ public Object get(Object target) throws HibernateException { try { return method.invoke(target, null); @@ -202,18 +205,37 @@ public class BasicPropertyAccessor implements PropertyAccessor { } } + /** + * {@inheritDoc} + */ public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + /** + * {@inheritDoc} + */ public Class getReturnType() { return method.getReturnType(); } + /** + * {@inheritDoc} + */ + public Member getMember() { + return method; + } + + /** + * {@inheritDoc} + */ public Method getMethod() { return method; } + /** + * {@inheritDoc} + */ public String getMethodName() { return method.getName(); } diff --git a/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java b/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java index ed445a7398..06a22548ea 100644 --- a/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; diff --git a/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java b/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java index 3082aa1b74..408bb7cbc8 100644 --- a/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -50,6 +50,10 @@ public class DirectPropertyAccessor implements PropertyAccessor { this.clazz = clazz; this.name = name; } + + /** + * {@inheritDoc} + */ public Object get(Object target) throws HibernateException { try { return field.get(target); @@ -59,16 +63,37 @@ public class DirectPropertyAccessor implements PropertyAccessor { } } + /** + * {@inheritDoc} + */ public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + /** + * {@inheritDoc} + */ + public Member getMember() { + return field; + } + + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + + /** + * {@inheritDoc} + */ public Class getReturnType() { return field.getType(); } @@ -91,12 +116,24 @@ public class DirectPropertyAccessor implements PropertyAccessor { this.clazz = clazz; this.name = name; } + + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + + /** + * {@inheritDoc} + */ public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { try { field.set(target, value); diff --git a/core/src/main/java/org/hibernate/property/Dom4jAccessor.java b/core/src/main/java/org/hibernate/property/Dom4jAccessor.java index e1c29eab2b..2d8cfaf075 100644 --- a/core/src/main/java/org/hibernate/property/Dom4jAccessor.java +++ b/core/src/main/java/org/hibernate/property/Dom4jAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.dom4j.Attribute; @@ -53,7 +53,6 @@ public class Dom4jAccessor implements PropertyAccessor { this.factory = factory; this.nodeName = nodeName; this.propertyType = propertyType; - } /** @@ -118,21 +117,28 @@ public class Dom4jAccessor implements PropertyAccessor { } /** - * Get the declared Java type + * {@inheritDoc} */ public Class getReturnType() { return Object.class; } /** - * Optional operation (return null) + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + + /** + * {@inheritDoc} */ public String getMethodName() { return null; } /** - * Optional operation (return null) + * {@inheritDoc} */ public Method getMethod() { return null; @@ -147,14 +153,14 @@ public class Dom4jAccessor implements PropertyAccessor { } /** - * Optional operation (return null) + * {@inheritDoc} */ public String getMethodName() { return null; } /** - * Optional operation (return null) + * {@inheritDoc} */ public Method getMethod() { return null; @@ -166,16 +172,17 @@ public class Dom4jAccessor implements PropertyAccessor { * @author Gavin King */ public static class TextGetter extends Dom4jGetter { - TextGetter(Type propertyType, SessionFactoryImplementor factory) { super(propertyType, factory); } + /** + * {@inheritDoc} + */ public Object get(Object owner) throws HibernateException { Element ownerElement = (Element) owner; return super.propertyType.fromXMLNode(ownerElement, super.factory); } - } /** @@ -184,19 +191,21 @@ public class Dom4jAccessor implements PropertyAccessor { */ public static class AttributeGetter extends Dom4jGetter { private final String attributeName; - + AttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) { super(propertyType, factory); attributeName = name.substring(1); } + /** + * {@inheritDoc} + */ public Object get(Object owner) throws HibernateException { Element ownerElement = (Element) owner; Node attribute = ownerElement.attribute(attributeName); return attribute==null ? null : super.propertyType.fromXMLNode(attribute, super.factory); } - } /** @@ -211,13 +220,15 @@ public class Dom4jAccessor implements PropertyAccessor { elementName = name; } + /** + * {@inheritDoc} + */ public Object get(Object owner) throws HibernateException { Element ownerElement = (Element) owner; Node element = ownerElement.element(elementName); return element==null ? null : super.propertyType.fromXMLNode(element, super.factory); } - } /** @@ -227,13 +238,16 @@ public class Dom4jAccessor implements PropertyAccessor { public static class ElementAttributeGetter extends Dom4jGetter { private final String elementName; private final String attributeName; - + ElementAttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) { super(propertyType, factory); elementName = name.substring( 0, name.indexOf('/') ); attributeName = name.substring( name.indexOf('/')+2 ); } + /** + * {@inheritDoc} + */ public Object get(Object owner) throws HibernateException { Element ownerElement = (Element) owner; @@ -260,12 +274,14 @@ public class Dom4jAccessor implements PropertyAccessor { * @author Gavin King */ public static class TextSetter extends Dom4jSetter { - TextSetter(Type propertyType) { super(propertyType); } - public void set(Object target, Object value, SessionFactoryImplementor factory) + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { Element owner = ( Element ) target; if ( !super.propertyType.isXMLElement() ) { //kinda ugly, but needed for collections with a "." node mapping @@ -277,7 +293,6 @@ public class Dom4jAccessor implements PropertyAccessor { } } } - } /** @@ -286,13 +301,16 @@ public class Dom4jAccessor implements PropertyAccessor { */ public static class AttributeSetter extends Dom4jSetter { private final String attributeName; - + AttributeSetter(String name, Type propertyType) { super(propertyType); attributeName = name.substring(1); } - public void set(Object target, Object value, SessionFactoryImplementor factory) + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { Element owner = ( Element ) target; Attribute attribute = owner.attribute(attributeName); @@ -307,7 +325,6 @@ public class Dom4jAccessor implements PropertyAccessor { super.propertyType.setToXMLNode(attribute, value, factory); } } - } /** @@ -322,7 +339,10 @@ public class Dom4jAccessor implements PropertyAccessor { elementName = name; } - public void set(Object target, Object value, SessionFactoryImplementor factory) + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { if (value!=CollectionType.UNFETCHED_COLLECTION) { Element owner = ( Element ) target; @@ -334,7 +354,6 @@ public class Dom4jAccessor implements PropertyAccessor { } } } - } /** @@ -351,7 +370,10 @@ public class Dom4jAccessor implements PropertyAccessor { attributeName = name.substring( name.indexOf('/')+2 ); } - public void set(Object target, Object value, SessionFactoryImplementor factory) + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { Element owner = ( Element ) target; Element element = owner.element(elementName); @@ -375,7 +397,6 @@ public class Dom4jAccessor implements PropertyAccessor { super.propertyType.setToXMLNode(attribute, value, factory); } } - } diff --git a/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java b/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java index a36dc9127c..f2e139084d 100755 --- a/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -38,29 +38,50 @@ import org.hibernate.engine.SessionFactoryImplementor; public class EmbeddedPropertyAccessor implements PropertyAccessor { public static final class EmbeddedGetter implements Getter { - private final Class clazz; EmbeddedGetter(Class clazz) { this.clazz = clazz; } + /** + * {@inheritDoc} + */ public Object get(Object target) throws HibernateException { return target; } + /** + * {@inheritDoc} + */ public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + /** + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public Class getReturnType() { return clazz; } @@ -71,23 +92,35 @@ public class EmbeddedPropertyAccessor implements PropertyAccessor { } public static final class EmbeddedSetter implements Setter { - private final Class clazz; EmbeddedSetter(Class clazz) { this.clazz = clazz; } + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } - public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {} - + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) { + } + + /** + * {@inheritDoc} + */ public String toString() { return "EmbeddedSetter(" + clazz.getName() + ')'; } diff --git a/core/src/main/java/org/hibernate/property/Getter.java b/core/src/main/java/org/hibernate/property/Getter.java index 7d6ceffae6..d062fadba0 100644 --- a/core/src/main/java/org/hibernate/property/Getter.java +++ b/core/src/main/java/org/hibernate/property/Getter.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.io.Serializable; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -58,17 +58,35 @@ public interface Getter extends Serializable { throws HibernateException; /** - * Get the declared Java type + * Retrieve the member to which this property maps. This might be the + * field or it might be the getter method. + * + * @return The mapped member. + */ + public Member getMember(); + + /** + * Retrieve the declared Java type + * + * @return The declared java type. */ public Class getReturnType(); /** + * Retrieve the getter-method name. + *

* Optional operation (return null) + * + * @return The name of the getter method, or null. */ public String getMethodName(); /** + * Retrieve the getter-method. + *

* Optional operation (return null) + * + * @return The getter method, or null. */ public Method getMethod(); } diff --git a/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java b/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java index 6272824086..80aa3d2355 100755 --- a/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -37,7 +37,6 @@ import org.hibernate.engine.SessionFactoryImplementor; * @author Gavin King */ public class IndexPropertyAccessor implements PropertyAccessor { - private final String propertyName; private final String entityName; @@ -45,6 +44,7 @@ public class IndexPropertyAccessor implements PropertyAccessor { * Constructs a new instance of IndexPropertyAccessor. * * @param collectionRole The collection role which this back ref references. + * @param entityName The name of the entity owning the collection. */ public IndexPropertyAccessor(String collectionRole, String entityName) { this.propertyName = collectionRole.substring( entityName.length()+1 ); @@ -64,20 +64,24 @@ public class IndexPropertyAccessor implements PropertyAccessor { * The Setter implementation for index backrefs. */ public static final class IndexSetter implements Setter { - + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } - public void set(Object target, Object value) { - // do nothing... - } - - public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor factory) { // do nothing... } @@ -88,7 +92,6 @@ public class IndexPropertyAccessor implements PropertyAccessor { * The Getter implementation for index backrefs. */ public class IndexGetter implements Getter { - public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException { if (session==null) { return BackrefPropertyAccessor.UNKNOWN; @@ -99,18 +102,37 @@ public class IndexPropertyAccessor implements PropertyAccessor { } } + /** + * {@inheritDoc} + */ public Object get(Object target) { return BackrefPropertyAccessor.UNKNOWN; } + /** + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public Class getReturnType() { return Object.class; } diff --git a/core/src/main/java/org/hibernate/property/MapAccessor.java b/core/src/main/java/org/hibernate/property/MapAccessor.java index 174c6acfaf..4077ef13bc 100644 --- a/core/src/main/java/org/hibernate/property/MapAccessor.java +++ b/core/src/main/java/org/hibernate/property/MapAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -36,33 +36,46 @@ import org.hibernate.engine.SessionImplementor; * @author Gavin King */ public class MapAccessor implements PropertyAccessor { - + /** + * {@inheritDoc} + */ public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException { return new MapGetter(propertyName); } + /** + * {@inheritDoc} + */ public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException { return new MapSetter(propertyName); } public static final class MapSetter implements Setter { - private String name; MapSetter(String name) { this.name = name; } + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { ( (Map) target ).put(name, value); @@ -71,33 +84,53 @@ public class MapAccessor implements PropertyAccessor { } public static final class MapGetter implements Getter { - private String name; MapGetter(String name) { this.name = name; } + /** + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public Object get(Object target) throws HibernateException { return ( (Map) target ).get(name); } + /** + * {@inheritDoc} + */ public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + /** + * {@inheritDoc} + */ public Class getReturnType() { return Object.class; } - } } diff --git a/core/src/main/java/org/hibernate/property/NoopAccessor.java b/core/src/main/java/org/hibernate/property/NoopAccessor.java index 683fca690f..55be85857a 100755 --- a/core/src/main/java/org/hibernate/property/NoopAccessor.java +++ b/core/src/main/java/org/hibernate/property/NoopAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.util.Map; import org.hibernate.HibernateException; @@ -38,11 +38,16 @@ import org.hibernate.engine.SessionImplementor; * @author Michael Bartmann */ public class NoopAccessor implements PropertyAccessor { - + /** + * {@inheritDoc} + */ public Getter getGetter(Class arg0, String arg1) throws PropertyNotFoundException { return new NoopGetter(); } + /** + * {@inheritDoc} + */ public Setter getSetter(Class arg0, String arg1) throws PropertyNotFoundException { return new NoopSetter(); } @@ -51,47 +56,73 @@ public class NoopAccessor implements PropertyAccessor { * A Getter which will always return null. It should not be called anyway. */ private static class NoopGetter implements Getter { - /** - * @return always null + * {@inheritDoc} + *

+ * Here we always return null */ public Object get(Object target) throws HibernateException { return null; } + /** + * {@inheritDoc} + */ public Object getForInsert(Object target, Map map, SessionImplementor arg1) throws HibernateException { return null; } + /** + * {@inheritDoc} + */ public Class getReturnType() { return Object.class; } + /** + * {@inheritDoc} + */ + public Member getMember() { + return null; + } + + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } - } /** * A Setter which will just do nothing. */ private static class NoopSetter implements Setter { - - public void set(Object target, Object value, SessionFactoryImplementor arg2) - throws HibernateException { - // do not do anything + /** + * {@inheritDoc} + */ + public void set(Object target, Object value, SessionFactoryImplementor arg2) { + // nothing to do } + /** + * {@inheritDoc} + */ public String getMethodName() { return null; } + /** + * {@inheritDoc} + */ public Method getMethod() { return null; } diff --git a/core/src/main/java/org/hibernate/property/PropertyAccessor.java b/core/src/main/java/org/hibernate/property/PropertyAccessor.java index cd7c8df3e2..0334fcbfc7 100644 --- a/core/src/main/java/org/hibernate/property/PropertyAccessor.java +++ b/core/src/main/java/org/hibernate/property/PropertyAccessor.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; @@ -29,15 +28,31 @@ import org.hibernate.PropertyNotFoundException; /** * Abstracts the notion of a "property". Defines a strategy for accessing the * value of an attribute. + * * @author Gavin King */ public interface PropertyAccessor { /** * Create a "getter" for the named attribute + * + * @param theClass The class on which the property is defined. + * @param propertyName The name of the property. + * + * @return An appropriate getter. + * + * @throws PropertyNotFoundException Indicates a problem interpretting the propertyName */ public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException; + /** * Create a "setter" for the named attribute + * + * @param theClass The class on which the property is defined. + * @param propertyName The name of the property. + * + * @return An appropriate setter + * + * @throws PropertyNotFoundException Indicates a problem interpretting the propertyName */ public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException; } diff --git a/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java b/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java index dd7a7de315..506ec07398 100644 --- a/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java +++ b/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; diff --git a/core/src/main/java/org/hibernate/property/Setter.java b/core/src/main/java/org/hibernate/property/Setter.java index ac9efdc612..ef95224574 100644 --- a/core/src/main/java/org/hibernate/property/Setter.java +++ b/core/src/main/java/org/hibernate/property/Setter.java @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; diff --git a/core/src/main/java/org/hibernate/property/package.html b/core/src/main/java/org/hibernate/property/package.html index c821e981c9..d0bec4a85d 100755 --- a/core/src/main/java/org/hibernate/property/package.html +++ b/core/src/main/java/org/hibernate/property/package.html @@ -1,10 +1,10 @@ diff --git a/core/src/main/java/org/hibernate/tuple/Tuplizer.java b/core/src/main/java/org/hibernate/tuple/Tuplizer.java index 0f11f1dc93..7fc2c9c015 100644 --- a/core/src/main/java/org/hibernate/tuple/Tuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/Tuplizer.java @@ -25,6 +25,7 @@ package org.hibernate.tuple; import org.hibernate.HibernateException; +import org.hibernate.property.Getter; /** * A tuplizer defines the contract for things which know how to manage @@ -56,24 +57,21 @@ import org.hibernate.HibernateException; * @author Steve Ebersole */ public interface Tuplizer { - /** * Extract the current values contained on the given entity. * * @param entity The entity from which to extract values. * @return The current property values. - * @throws HibernateException */ - public Object[] getPropertyValues(Object entity) throws HibernateException; + public Object[] getPropertyValues(Object entity); /** * Inject the given values into the given entity. * * @param entity The entity. * @param values The values to be injected. - * @throws HibernateException */ - public void setPropertyValues(Object entity, Object[] values) throws HibernateException; + public void setPropertyValues(Object entity, Object[] values); /** * Extract the value of a particular property from the given entity. @@ -81,17 +79,15 @@ public interface Tuplizer { * @param entity The entity from which to extract the property value. * @param i The index of the property for which to extract the value. * @return The current value of the given property on the given entity. - * @throws HibernateException */ - public Object getPropertyValue(Object entity, int i) throws HibernateException; + public Object getPropertyValue(Object entity, int i); /** * Generate a new, empty entity. * * @return The new, empty entity instance. - * @throws HibernateException */ - public Object instantiate() throws HibernateException; + public Object instantiate(); /** * Is the given object considered an instance of the the entity (acconting @@ -115,4 +111,11 @@ public interface Tuplizer { */ public Class getMappedClass(); + /** + * Retrieve the getter for the specified property. + * + * @param i The property index. + * @return The property getter. + */ + public Getter getGetter(int i); } diff --git a/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java b/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java index 218f97e887..78ab34f544 100644 --- a/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java @@ -42,7 +42,6 @@ import org.hibernate.property.Setter; * @author Steve Ebersole */ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { - protected final Getter[] getters; protected final Setter[] setters; protected final int propertySpan; @@ -71,15 +70,6 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { i++; } hasCustomAccessors = foundCustomAccessor; - - String[] getterNames = new String[propertySpan]; - String[] setterNames = new String[propertySpan]; - Class[] propTypes = new Class[propertySpan]; - for ( int j = 0; j < propertySpan; j++ ) { - getterNames[j] = getters[j].getMethodName(); - setterNames[j] = setters[j].getMethodName(); - propTypes[j] = getters[j].getReturnType(); - } instantiator = buildInstantiator( component ); } @@ -128,4 +118,7 @@ public abstract class AbstractComponentTuplizer implements ComponentTuplizer { throw new UnsupportedOperationException(); } + public Getter getGetter(int i) { + return getters[i]; + } } diff --git a/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java b/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java index d748a2cd1e..d1358b4bc9 100644 --- a/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java @@ -51,7 +51,6 @@ import org.hibernate.util.ReflectHelper; * @author Steve Ebersole */ public class PojoComponentTuplizer extends AbstractComponentTuplizer { - private final Class componentClass; private ReflectionOptimizer optimizer; private final Getter parentGetter; diff --git a/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java index a7c5f6293b..c59da81306 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java @@ -140,7 +140,9 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { Property property = (Property) iter.next(); getters[i] = buildPropertyGetter(property, mappingInfo); setters[i] = buildPropertySetter(property, mappingInfo); - if ( !property.isBasicPropertyAccessor() ) foundCustomAccessor = true; + if ( !property.isBasicPropertyAccessor() ) { + foundCustomAccessor = true; + } i++; } hasCustomAccessors = foundCustomAccessor; @@ -423,4 +425,18 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { return getClass().getName() + '(' + getEntityMetamodel().getName() + ')'; } + public Getter getIdentifierGetter() { + return idGetter; + } + + public Getter getVersionGetter() { + if ( getEntityMetamodel().isVersioned() ) { + return getGetter( getEntityMetamodel().getVersionPropertyIndex() ); + } + return null; + } + + public Getter getGetter(int i) { + return getters[i]; + } } diff --git a/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java index a506b2ee5d..9f0ee33bb7 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java @@ -30,6 +30,7 @@ import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.EntityNameResolver; import org.hibernate.EntityMode; +import org.hibernate.property.Getter; import org.hibernate.tuple.Tuplizer; import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SessionFactoryImplementor; @@ -238,4 +239,18 @@ public interface EntityTuplizer extends Tuplizer { * @throws HibernateException If we are unable to determine an entity-name within the inheritence hierarchy. */ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory); + + /** + * Retrieve the getter for the identifier property. May return null. + * + * @return The getter for the identifier property. + */ + public Getter getIdentifierGetter(); + + /** + * Retrieve the getter for the version property. May return null. + * + * @return The getter for the version property. + */ + public Getter getVersionGetter(); } \ No newline at end of file diff --git a/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java b/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java index 001ebe63d7..3828a1306a 100644 --- a/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java +++ b/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java @@ -64,7 +64,6 @@ import org.hibernate.util.ReflectHelper; * @author Gavin King */ public class PojoEntityTuplizer extends AbstractEntityTuplizer { - static final Logger log = LoggerFactory.getLogger( PojoEntityTuplizer.class ); private final Class mappedClass; diff --git a/core/src/main/java/org/hibernate/type/ComponentType.java b/core/src/main/java/org/hibernate/type/ComponentType.java index cf69a6ecc7..3bb56ef222 100644 --- a/core/src/main/java/org/hibernate/type/ComponentType.java +++ b/core/src/main/java/org/hibernate/type/ComponentType.java @@ -38,6 +38,7 @@ import org.hibernate.EntityMode; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.PropertyNotFoundException; import org.hibernate.engine.CascadeStyle; import org.hibernate.engine.Mapping; import org.hibernate.engine.SessionFactoryImplementor; @@ -88,6 +89,10 @@ public class ComponentType extends AbstractType implements AbstractComponentType this.tuplizerMapping = metamodel.getTuplizerMapping(); } + public EntityModeToTuplizerMapping getTuplizerMapping() { + return tuplizerMapping; + } + public int[] sqlTypes(Mapping mapping) throws MappingException { //Not called at runtime so doesn't matter if its slow :) int[] sqlTypes = new int[getColumnSpan( mapping )]; @@ -656,4 +661,15 @@ public class ComponentType extends AbstractType implements AbstractComponentType return false; } + public int getPropertyIndex(String name) { + String[] names = getPropertyNames(); + for ( int i = 0, max = names.length; i < max; i++ ) { + if ( names[i].equals( name ) ) { + return i; + } + } + throw new PropertyNotFoundException( + "Unable to locate property named " + name + " on " + getReturnedClass().getName() + ); + } } diff --git a/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java index 07d3a741f6..7adefd1254 100755 --- a/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/EntityManagerFactoryImpl.java @@ -35,6 +35,7 @@ import javax.persistence.spi.PersistenceUnitTransactionType; import javax.persistence.spi.LoadState; import org.hibernate.SessionFactory; +import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.mapping.PersistentClass; import org.hibernate.cfg.Configuration; import org.hibernate.ejb.criteria.CriteriaBuilderImpl; @@ -71,7 +72,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory { final Iterator classes = cfg.getClassMappings(); //a safe guard till we are confident that metamodel is wll tested if ( !"disabled".equalsIgnoreCase( cfg.getProperty( "hibernate.ejb.metamodel.generation" ) ) ) { - this.metamodel = new MetamodelImpl( classes ); + this.metamodel = MetamodelImpl.buildMetamodel( classes, ( SessionFactoryImplementor ) sessionFactory ); } else { this.metamodel = null; diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java index f093fdeeae..4ad1124b2e 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AbstractIdentifiableType.java @@ -87,16 +87,18 @@ public abstract class AbstractIdentifiableType * {@inheritDoc} */ @SuppressWarnings({ "unchecked" }) - public SingularAttribute getId(Class type) { + public SingularAttribute getId(Class javaType) { final SingularAttribute id_; if ( id != null ) { checkSimpleId(); id_ = ( SingularAttribute ) id; + if ( javaType != id.getJavaType() ) { + throw new IllegalArgumentException( "Id attribute was not of specified type : " + javaType.getName() ); + } } else { - id_ = requireSupertype().getId( type ); + id_ = requireSupertype().getId( javaType ); } - // TODO : check that type and id_.getJavaType() are related return id_; } @@ -117,10 +119,12 @@ public abstract class AbstractIdentifiableType * {@inheritDoc} */ @SuppressWarnings({ "unchecked" }) - public SingularAttribute getDeclaredId(Class yClass) { + public SingularAttribute getDeclaredId(Class javaType) { checkDeclaredId(); checkSimpleId(); - // TODO : check that type and id.getJavaType() are related + if ( javaType != id.getJavaType() ) { + throw new IllegalArgumentException( "Id attribute was not of specified type : " + javaType.getName() ); + } return (SingularAttribute) id; } @@ -177,18 +181,20 @@ public abstract class AbstractIdentifiableType * {@inheritDoc} */ @SuppressWarnings({ "unchecked" }) - public SingularAttribute getVersion(Class type) { + public SingularAttribute getVersion(Class javaType) { if ( ! hasVersionAttribute() ) { return null; } final SingularAttribute version_; if ( version != null ) { version_ = ( SingularAttribute ) version; + if ( javaType != version.getJavaType() ) { + throw new IllegalArgumentException( "Version attribute was not of specified type : " + javaType.getName() ); + } } else { - version_ = requireSupertype().getVersion( type ); + version_ = requireSupertype().getVersion( javaType ); } - // TODO : check that type and version_.getJavaType() are related return version_; } @@ -196,9 +202,11 @@ public abstract class AbstractIdentifiableType * {@inheritDoc} */ @SuppressWarnings({ "unchecked" }) - public SingularAttribute getDeclaredVersion(Class yClass) { + public SingularAttribute getDeclaredVersion(Class javaType) { checkDeclaredVersion(); - // TODO : check that type and version_.getJavaType() are related + if ( javaType != version.getJavaType() ) { + throw new IllegalArgumentException( "Version attribute was not of specified type : " + javaType.getName() ); + } return ( SingularAttribute ) version; } diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java index 44cad06014..207d55ffd7 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/AttributeFactory.java @@ -23,18 +23,22 @@ */ package org.hibernate.ejb.metamodel; -import java.util.Iterator; import java.lang.reflect.Member; +import java.util.Iterator; import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.Type; +import org.hibernate.EntityMode; +import org.hibernate.type.EmbeddedComponentType; +import org.hibernate.type.ComponentType; +import org.hibernate.annotations.common.AssertionFailure; +import org.hibernate.mapping.Collection; +import org.hibernate.mapping.Component; +import org.hibernate.mapping.Map; +import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.Property; import org.hibernate.mapping.Value; -import org.hibernate.mapping.Collection; -import org.hibernate.mapping.Map; -import org.hibernate.mapping.Component; -import org.hibernate.mapping.OneToMany; -import org.hibernate.annotations.common.AssertionFailure; +import org.hibernate.tuple.entity.EntityMetamodel; /** * TODO : javadoc @@ -57,12 +61,12 @@ public class AttributeFactory { attribute = buildPluralAttribute( ownerType, property, attrContext ); } else { - final Type attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() ); + final Type attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() ); attribute = new SingularAttributeImpl( property.getName(), property.getType().getReturnedClass(), ownerType, - determineJavaMember( property ), + determineStandardJavaMember( ownerType, property ), false, false, property.isOptional(), @@ -76,19 +80,19 @@ public class AttributeFactory { @SuppressWarnings( "unchecked" ) private AttributeImplementor buildPluralAttribute(AbstractManagedType ownerType, Property property, AttributeContext attrContext) { AttributeImplementor attribute; - final Type attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() ); + final Type attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() ); final Class collectionClass = (Class) attrContext.getCollectionClass(); if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) { - final Type keyType = getType( attrContext.getKeyTypeStatus(), attrContext.getKeyValue() ); + final Type keyType = getType( ownerType, attrContext.getKeyTypeStatus(), attrContext.getKeyValue() ); attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType ) - .member( determineJavaMember( property ) ) + .member( determineStandardJavaMember( ownerType, property ) ) .property( property ) .persistentAttributeType( attrContext.getElementAttributeType() ) .build(); } else { attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, null ) - .member( determineJavaMember( property ) ) + .member( determineStandardJavaMember( ownerType, property ) ) .property( property ) .persistentAttributeType( attrContext.getElementAttributeType() ) .build(); @@ -96,13 +100,13 @@ public class AttributeFactory { return attribute; } - private Type getType(AttributeContext.TypeStatus elementTypeStatus, Value value) { + private Type getType(AbstractManagedType owner, AttributeContext.TypeStatus elementTypeStatus, Value value) { final org.hibernate.type.Type type = value.getType(); switch ( elementTypeStatus ) { case BASIC: return buildBasicType( type ); case EMBEDDABLE: - return buildEmbeddableType( value, type ); + return buildEmbeddableType( owner, value, type ); case ENTITY: return buildEntityType( type ); default: @@ -124,10 +128,10 @@ public class AttributeFactory { } @SuppressWarnings( "unchecked" ) - private Type buildEmbeddableType(Value value, org.hibernate.type.Type type) { + private Type buildEmbeddableType(AbstractManagedType owner, Value value, org.hibernate.type.Type type) { //build embedable type final Class clazz = type.getReturnedClass(); - final EmbeddableTypeImpl embeddableType = new EmbeddableTypeImpl( clazz ); + final EmbeddableTypeImpl embeddableType = new EmbeddableTypeImpl( clazz, owner, (ComponentType) type ); context.registerEmbeddedableType( embeddableType ); final Component component = (Component) value; final Iterator subProperties = component.getPropertyIterator(); @@ -142,38 +146,115 @@ public class AttributeFactory { @SuppressWarnings({ "unchecked" }) public SingularAttributeImpl buildIdAttribute(AbstractManagedType ownerType, Property property) { final AttributeContext attrContext = getAttributeContext( property ); - final Type attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() ); + final Type attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() ); final Class idJavaType = property.getType().getReturnedClass(); return new SingularAttributeImpl.Identifier( property.getName(), idJavaType, ownerType, - determineJavaMember( property ), + determineIdentifierJavaMember( ownerType, property ), attrType, attrContext.getElementAttributeType() ); } - @SuppressWarnings({ "UnusedDeclaration" }) - private Member determineJavaMember(Property property) { - return null; + private Member determineIdentifierJavaMember(AbstractManagedType ownerType, Property property) { +// see below +// final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( property ); + final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType ); + if ( ! property.getName().equals( entityMetamodel.getIdentifierProperty().getName() ) ) { + // this *should* indicate processing part of an IdClass... + return determineVirtualIdentifierJavaMember( entityMetamodel, property ); + } + return entityMetamodel.getTuplizer( EntityMode.POJO ).getIdentifierGetter().getMember(); + } + + private Member determineVirtualIdentifierJavaMember(EntityMetamodel entityMetamodel, Property property) { + if ( ! entityMetamodel.getIdentifierProperty().isVirtual() ) { + throw new IllegalArgumentException( "expecting IdClass mapping" ); + } + org.hibernate.type.Type type = entityMetamodel.getIdentifierProperty().getType(); + if ( ! EmbeddedComponentType.class.isInstance( type ) ) { + throw new IllegalArgumentException( "expecting IdClass mapping" ); + } + final EmbeddedComponentType componentType = (EmbeddedComponentType) type; + return componentType.getTuplizerMapping() + .getTuplizer( EntityMode.POJO ) + .getGetter( componentType.getPropertyIndex( property.getName() ) ) + .getMember(); + } + +// getting the owning PersistentClass from the Property is broken in certain cases with annotations... +// private EntityMetamodel getDeclarerEntityMetamodel(Property property) { +// return context.getSessionFactory() +// .getEntityPersister( property.getPersistentClass().getEntityName() ) +// .getEntityMetamodel(); +// } +// so we use the owner's java class to lookup the persister/entitymetamodel + private EntityMetamodel getDeclarerEntityMetamodel(AbstractManagedType ownerType) { + return context.getSessionFactory() + .getEntityPersister( ownerType.getJavaType().getName() ) + .getEntityMetamodel(); + } + +// getting the owning PersistentClass from the Property is broken in certain cases with annotations... +// private Member determineStandardJavaMember(Property property) { +// final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( property ); +// +// final String propertyName = property.getName(); +// final int index = entityMetamodel.getPropertyIndex( propertyName ); +// return entityMetamodel.getTuplizer( EntityMode.POJO ).getGetter( index ).getMember(); +// } +// so we use the owner's java class to lookup the persister/entitymetamodel + private Member determineStandardJavaMember(AbstractManagedType ownerType, Property property) { + if ( Type.PersistenceType.EMBEDDABLE == ownerType.getPersistenceType() ) { + EmbeddableTypeImpl embeddableType = ( EmbeddableTypeImpl ) ownerType; + return embeddableType.getHibernateType().getTuplizerMapping() + .getTuplizer( EntityMode.POJO ) + .getGetter( embeddableType.getHibernateType().getPropertyIndex( property.getName() ) ) + .getMember(); + } + else if ( Type.PersistenceType.ENTITY == ownerType.getPersistenceType() ) { + final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType ); + final String propertyName = property.getName(); + final Integer index = entityMetamodel.getPropertyIndexOrNull( propertyName ); + if ( index == null ) { + // just like in #determineIdentifierJavaMember , this *should* indicate we have an IdClass mapping + return determineVirtualIdentifierJavaMember( entityMetamodel, property ); + } + else { + return entityMetamodel.getTuplizer( EntityMode.POJO ).getGetter( index ).getMember(); + } + } + else { + throw new IllegalArgumentException( "Unexpected owner type : " + ownerType.getPersistenceType() ); + } } @SuppressWarnings({ "unchecked" }) public SingularAttributeImpl buildVerisonAttribute(AbstractManagedType ownerType, Property property) { final AttributeContext attrContext = getAttributeContext( property ); final Class javaType = property.getType().getReturnedClass(); - final Type attrType = getType( attrContext.getElementTypeStatus(), attrContext.getElementValue() ); + final Type attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() ); return new SingularAttributeImpl.Version( property.getName(), javaType, ownerType, - determineJavaMember( property ), + determineVersionJavaMember( ownerType, property ), attrType, attrContext.getElementAttributeType() ); } + private Member determineVersionJavaMember(AbstractManagedType ownerType, Property property) { + final EntityMetamodel entityMetamodel = getDeclarerEntityMetamodel( ownerType ); + if ( ! property.getName().equals( entityMetamodel.getVersionProperty().getName() ) ) { + // this should never happen, but to be safe... + throw new IllegalArgumentException( "Given property did not match declared version property" ); + } + return entityMetamodel.getTuplizer( EntityMode.POJO ).getIdentifierGetter().getMember(); + } + private static class AttributeContext { private final Value elementValue; private final TypeStatus typeStatus; diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java index afc0d486ec..83ab386c98 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/EmbeddableTypeImpl.java @@ -21,11 +21,10 @@ */ package org.hibernate.ejb.metamodel; -import java.util.Iterator; import java.io.Serializable; import javax.persistence.metamodel.EmbeddableType; -import org.hibernate.mapping.Property; +import org.hibernate.type.ComponentType; /** * @author Emmanuel Bernard @@ -34,11 +33,24 @@ public class EmbeddableTypeImpl extends AbstractManagedType implements EmbeddableType, Serializable { - public EmbeddableTypeImpl(Class javaType) { + private final AbstractManagedType parent; + private final ComponentType hibernateType; + + public EmbeddableTypeImpl(Class javaType, AbstractManagedType parent, ComponentType hibernateType) { super( javaType, null ); + this.parent = parent; + this.hibernateType = hibernateType; } public PersistenceType getPersistenceType() { return PersistenceType.EMBEDDABLE; } + + public AbstractManagedType getParent() { + return parent; + } + + public ComponentType getHibernateType() { + return hibernateType; + } } diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java index ec91638372..c56ab14f86 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetadataContext.java @@ -33,6 +33,7 @@ import javax.persistence.metamodel.SingularAttribute; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; +import org.hibernate.engine.SessionFactoryImplementor; /** * Defines a context for storing information during the building of the {@link MetamodelImpl}. @@ -44,6 +45,7 @@ import org.hibernate.mapping.Property; * @author Emmanuel Bernard */ class MetadataContext { + private final SessionFactoryImplementor sessionFactory; private final AttributeFactory attributeFactory = new AttributeFactory( this ); private HashMap,EntityTypeImpl> entityTypes @@ -55,6 +57,14 @@ class MetadataContext { private HashMap, EmbeddableTypeImpl> embeddables = new HashMap, EmbeddableTypeImpl>(); + public MetadataContext(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + } + + /*package*/ SessionFactoryImplementor getSessionFactory() { + return sessionFactory; + } + /** * Given a Hibernate {@link PersistentClass}, locate the corresponding JPA {@link org.hibernate.type.EntityType} * implementation. May retur null if the given {@link PersistentClass} has not yet been processed. diff --git a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java index 7e24375e52..2f9b56233b 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/metamodel/MetamodelImpl.java @@ -32,6 +32,7 @@ import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.EmbeddableType; import org.hibernate.mapping.PersistentClass; +import org.hibernate.engine.SessionFactoryImplementor; /** * Hibernate implementation of the JPA {@link Metamodel} contract. @@ -44,21 +45,25 @@ public class MetamodelImpl implements Metamodel, Serializable { private final Map, EmbeddableTypeImpl> embeddables; /** - * Instantiate the metamodel from the collection of Hibernate {@link PersistentClass} models. + * Build the metamodel using the information from the collection of Hibernate + * {@link PersistentClass} models as well as the Hibernate {@link SessionFactory}. * - * @param persistentClasses An iterator over the Hibernate {@link PersistentClass} models. + * @param persistentClasses Iterator over the Hibernate (config-time) metamodel + * @param sessionFactory The Hibernate session factry. + * @return The built metamodel */ - public MetamodelImpl(Iterator persistentClasses) { - MetadataContext context = new MetadataContext(); + public static MetamodelImpl buildMetamodel( + Iterator persistentClasses, + SessionFactoryImplementor sessionFactory) { + MetadataContext context = new MetadataContext( sessionFactory ); while ( persistentClasses.hasNext() ) { locateOrBuildEntityType( persistentClasses.next(), context ); } - this.entities = context.getEntityTypeMap(); context.wrapUp(); - this.embeddables = context.getEmbeddableTypeMap(); + return new MetamodelImpl( context.getEntityTypeMap(), context.getEmbeddableTypeMap() ); } - private EntityTypeImpl locateOrBuildEntityType(PersistentClass persistentClass, MetadataContext context) { + private static EntityTypeImpl locateOrBuildEntityType(PersistentClass persistentClass, MetadataContext context) { EntityTypeImpl entityType = context.locateEntityType( persistentClass ); if ( entityType == null ) { entityType = buildEntityType( persistentClass, context ); @@ -67,7 +72,7 @@ public class MetamodelImpl implements Metamodel, Serializable { } @SuppressWarnings({ "unchecked" }) - private EntityTypeImpl buildEntityType(PersistentClass persistentClass, MetadataContext context) { + private static EntityTypeImpl buildEntityType(PersistentClass persistentClass, MetadataContext context) { final PersistentClass superPersistentClass = persistentClass.getSuperclass(); final EntityTypeImpl superEntityType = superPersistentClass == null ? null @@ -84,6 +89,19 @@ public class MetamodelImpl implements Metamodel, Serializable { return entityType; } + /** + * Instantiate the metamodel. + * + * @param entities The entity mappings. + * @param embeddables The embeddable (component) mappings. + */ + private MetamodelImpl( + Map, EntityTypeImpl> entities, + Map, EmbeddableTypeImpl> embeddables) { + this.entities = entities; + this.embeddables = embeddables; + } + /** * {@inheritDoc} */ diff --git a/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java b/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java index 3501314e28..fc28f252df 100644 --- a/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java +++ b/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java @@ -37,6 +37,16 @@ public class MetadataTest extends TestCase { final SingularAttribute id = fridgeType.getDeclaredId( Long.class ); assertNotNull( id ); assertTrue( id.isId() ); + try { + fridgeType.getDeclaredId( java.util.Date.class ); + fail( "expecting failure" ); + } + catch ( IllegalArgumentException ignore ) { + // expected result + } + final SingularAttribute id2 = fridgeType.getId( Long.class ); + assertNotNull( id2 ); + assertEquals( Fridge.class.getName(), fridgeType.getName() ); assertEquals( Long.class, fridgeType.getIdType().getJavaType() ); assertTrue( fridgeType.hasSingleIdAttribute() );