Add support for the new JPA 2 API from July 23 2009 (only the top level package. Subpackages have not been updated. Also partially implement PersistenceUnitUtil
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17305 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
5f27074c73
commit
28207a2eb1
|
@ -38,6 +38,7 @@ import javax.persistence.PersistenceContextType;
|
|||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.QueryBuilder;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
|
@ -125,7 +126,28 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
}
|
||||
|
||||
public Query createQuery(CriteriaQuery criteriaQuery) {
|
||||
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) {
|
||||
throw new UnsupportedOperationException( "Not yet implemented" );
|
||||
}
|
||||
|
||||
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
|
||||
// TODO-STEVE : here is the interpretation/compilation portion.
|
||||
// One option is to build on top of the existing
|
||||
// org.hibernate.loader.custom.CustomQuery infastructure
|
||||
// (which is how native sql queries are implemented e.g.).
|
||||
// If so, then here we could interpret the criteria into
|
||||
// a CustomQuery instance which is passed into the
|
||||
// Query instance returned here. We would then call into
|
||||
// the various SessionImplementor methods for execution
|
||||
// such as #listCustomQuery and #scrollCustomQuery.
|
||||
//
|
||||
// The drawback to this (^^) approach is that CustomQuery +
|
||||
// SessionImplementor combo does not support #executeUpdate
|
||||
// processing...
|
||||
throw new UnsupportedOperationException( "Not yet implemented!" );
|
||||
}
|
||||
|
||||
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery, Class<T> resultClass) {
|
||||
// TODO-STEVE : here is the interpretation/compilation portion.
|
||||
// One option is to build on top of the existing
|
||||
// org.hibernate.loader.custom.CustomQuery infastructure
|
||||
|
@ -160,6 +182,11 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
}
|
||||
}
|
||||
|
||||
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
|
||||
throw new UnsupportedOperationException( "Not yet implemented" );
|
||||
}
|
||||
|
||||
|
||||
public Query createNativeQuery(String sqlString) {
|
||||
//adjustFlushMode();
|
||||
try {
|
||||
|
|
|
@ -23,6 +23,7 @@ package org.hibernate.ejb;
|
|||
|
||||
import java.util.Map;
|
||||
import javax.persistence.PersistenceContextType;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
|
|
@ -28,15 +28,19 @@ import java.io.Serializable;
|
|||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContextType;
|
||||
import javax.persistence.Cache;
|
||||
import javax.persistence.PersistenceUnitUtil;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
import javax.persistence.criteria.QueryBuilder;
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
import javax.persistence.spi.LoadState;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.ejb.criteria.QueryBuilderImpl;
|
||||
import org.hibernate.ejb.metamodel.MetamodelImpl;
|
||||
import org.hibernate.ejb.util.PersistenceUtilHelper;
|
||||
|
||||
/**
|
||||
* Actual Hiberate implementation of {@link javax.persistence.EntityManagerFactory}.
|
||||
|
@ -52,6 +56,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
|||
private final Class sessionInterceptorClass;
|
||||
private final QueryBuilderImpl criteriaQueryBuilder;
|
||||
private final Metamodel metamodel;
|
||||
private final HibernatePersistenceUnitUtil util;
|
||||
|
||||
public EntityManagerFactoryImpl(
|
||||
SessionFactory sessionFactory,
|
||||
|
@ -73,6 +78,7 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
|||
this.metamodel = null;
|
||||
}
|
||||
this.criteriaQueryBuilder = new QueryBuilderImpl( this );
|
||||
this.util = new HibernatePersistenceUnitUtil( this );
|
||||
}
|
||||
|
||||
public EntityManager createEntityManager() {
|
||||
|
@ -114,6 +120,10 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
|||
return new JPACache( sessionFactory );
|
||||
}
|
||||
|
||||
public PersistenceUnitUtil getPersistenceUnitUtil() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return ! sessionFactory.isClosed();
|
||||
}
|
||||
|
@ -148,4 +158,35 @@ public class EntityManagerFactoryImpl implements HibernateEntityManagerFactory {
|
|||
// sessionFactory.getCache().evictQueryRegions();
|
||||
}
|
||||
}
|
||||
|
||||
private static class HibernatePersistenceUnitUtil implements PersistenceUnitUtil, Serializable {
|
||||
private final EntityManagerFactoryImpl emf;
|
||||
|
||||
private HibernatePersistenceUnitUtil(EntityManagerFactoryImpl emf) {
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
public boolean isLoaded(Object entity, String attributeName) {
|
||||
LoadState state = PersistenceUtilHelper.isLoadedWithoutReference( entity, attributeName );
|
||||
if (state == LoadState.LOADED) {
|
||||
return true;
|
||||
}
|
||||
else if (state == LoadState.NOT_LOADED ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return PersistenceUtilHelper.isLoadedWithReference( entity, attributeName ) != LoadState.NOT_LOADED;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public boolean isLoaded(Object entity) {
|
||||
return PersistenceUtilHelper.isLoaded( entity ) != LoadState.NOT_LOADED;
|
||||
}
|
||||
|
||||
public Object getIdentifier(Object entity) {
|
||||
throw new UnsupportedOperationException( "Not yet implemented" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import javax.persistence.spi.PersistenceUnitInfo;
|
|||
import javax.persistence.spi.LoadState;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.ejb.util.PersistenceUtilHelper;
|
||||
import org.hibernate.intercept.FieldInterceptionHelper;
|
||||
import org.hibernate.intercept.FieldInterceptor;
|
||||
import org.hibernate.collection.PersistentCollection;
|
||||
|
@ -170,140 +171,15 @@ public class HibernatePersistence implements javax.persistence.spi.PersistencePr
|
|||
}
|
||||
|
||||
public LoadState isLoadedWithoutReference(Object proxy, String property) {
|
||||
Object entity;
|
||||
boolean sureFromUs = false;
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
return LoadState.NOT_LOADED;
|
||||
}
|
||||
else {
|
||||
entity = li.getImplementation();
|
||||
}
|
||||
sureFromUs = true;
|
||||
}
|
||||
else {
|
||||
entity = proxy;
|
||||
}
|
||||
|
||||
//we are instrumenting but we can't assume we are the only ones
|
||||
if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
|
||||
FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
|
||||
final boolean isInitialized = interceptor == null || interceptor.isInitialized( property );
|
||||
LoadState state;
|
||||
if (isInitialized && interceptor != null) {
|
||||
//property is loaded according to bytecode enhancement, but is it loaded as far as association?
|
||||
//it's ours, we can read
|
||||
state = isLoaded( get( entity, property ) );
|
||||
//it's ours so we know it's loaded
|
||||
if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
|
||||
}
|
||||
else if ( interceptor != null && (! isInitialized)) {
|
||||
state = LoadState.NOT_LOADED;
|
||||
}
|
||||
else if ( sureFromUs ) { //interceptor == null
|
||||
//property is loaded according to bytecode enhancement, but is it loaded as far as association?
|
||||
//it's ours, we can read
|
||||
state = isLoaded( get( entity, property ) );
|
||||
//it's ours so we know it's loaded
|
||||
if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
|
||||
}
|
||||
else {
|
||||
state = LoadState.UNKNOWN;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
else {
|
||||
//can't do sureFromUs ? LoadState.LOADED : LoadState.UNKNOWN;
|
||||
//is that an association?
|
||||
return LoadState.UNKNOWN;
|
||||
}
|
||||
return PersistenceUtilHelper.isLoadedWithoutReference( proxy, property );
|
||||
}
|
||||
|
||||
public LoadState isLoadedWithReference(Object proxy, String property) {
|
||||
//for sure we don't instrument and for sure it's not a lazy proxy
|
||||
Object object = get(proxy, property);
|
||||
return isLoaded( object );
|
||||
}
|
||||
|
||||
private Object get(Object proxy, String property) {
|
||||
final Class<?> clazz = proxy.getClass();
|
||||
try {
|
||||
try {
|
||||
final Field field = clazz.getField( property );
|
||||
setAccessibility( field );
|
||||
return field.get( proxy );
|
||||
}
|
||||
catch ( NoSuchFieldException e ) {
|
||||
final Method method = getMethod( clazz, property );
|
||||
if (method != null) {
|
||||
setAccessibility( method );
|
||||
return method.invoke( proxy );
|
||||
}
|
||||
else {
|
||||
throw new PersistenceException( "Unable to find field or method: "
|
||||
+ clazz + "#"
|
||||
+ property);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IllegalAccessException e ) {
|
||||
throw new PersistenceException( "Unable to access field or method: "
|
||||
+ clazz + "#"
|
||||
+ property, e);
|
||||
}
|
||||
catch ( InvocationTargetException e ) {
|
||||
throw new PersistenceException( "Unable to access field or method: "
|
||||
+ clazz + "#"
|
||||
+ property, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method with the specified name or <code>null</code> if it does not exist.
|
||||
*
|
||||
* @param clazz The class to check.
|
||||
* @param methodName The method name.
|
||||
*
|
||||
* @return Returns the method with the specified name or <code>null</code> if it does not exist.
|
||||
*/
|
||||
public static Method getMethod(Class<?> clazz, String methodName) {
|
||||
try {
|
||||
char string[] = methodName.toCharArray();
|
||||
string[0] = Character.toUpperCase( string[0] );
|
||||
methodName = new String( string );
|
||||
try {
|
||||
return clazz.getMethod( "get" + methodName );
|
||||
}
|
||||
catch ( NoSuchMethodException e ) {
|
||||
return clazz.getMethod( "is" + methodName );
|
||||
}
|
||||
}
|
||||
catch ( NoSuchMethodException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAccessibility(Member member) {
|
||||
if ( !Modifier.isPublic( member.getModifiers() ) ) {
|
||||
//Sun's ease of use, sigh...
|
||||
( ( AccessibleObject ) member ).setAccessible( true );
|
||||
}
|
||||
return PersistenceUtilHelper.isLoadedWithReference( proxy, property );
|
||||
}
|
||||
|
||||
public LoadState isLoaded(Object o) {
|
||||
if ( o instanceof HibernateProxy ) {
|
||||
final boolean isInitialized = !( ( HibernateProxy ) o ).getHibernateLazyInitializer().isUninitialized();
|
||||
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
|
||||
}
|
||||
else if ( o instanceof PersistentCollection ) {
|
||||
final boolean isInitialized = ( ( PersistentCollection ) o ).wasInitialized();
|
||||
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
|
||||
}
|
||||
else {
|
||||
return LoadState.UNKNOWN;
|
||||
}
|
||||
return PersistenceUtilHelper.isLoaded(o);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,6 +38,7 @@ import javax.persistence.TemporalType;
|
|||
import static javax.persistence.TemporalType.*;
|
||||
import javax.persistence.TransactionRequiredException;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.Parameter;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -395,13 +396,48 @@ public class QueryImpl implements Query, HibernateQuery {
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> getNamedParameters() {
|
||||
//FIXME
|
||||
public Set<Parameter<?>> getParameters() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public List getPositionalParameters() {
|
||||
//FIXME
|
||||
public Parameter<?> getParameter(String name) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public Parameter<?> getParameter(int position) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public <T> Parameter<T> getParameter(String name, Class<T> type) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public <T> Parameter<T> getParameter(int position, Class<T> type) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public boolean isBound(Parameter<?> param) {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public <T> T getParameterValue(Parameter<T> param) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public Object getParameterValue(String name) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
//FIXME
|
||||
public Object getParameterValue(int position) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
package org.hibernate.ejb.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import javax.persistence.spi.LoadState;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.intercept.FieldInterceptionHelper;
|
||||
import org.hibernate.intercept.FieldInterceptor;
|
||||
import org.hibernate.collection.PersistentCollection;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class PersistenceUtilHelper {
|
||||
public static LoadState isLoadedWithoutReference(Object proxy, String property) {
|
||||
Object entity;
|
||||
boolean sureFromUs = false;
|
||||
if ( proxy instanceof HibernateProxy ) {
|
||||
LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
|
||||
if ( li.isUninitialized() ) {
|
||||
return LoadState.NOT_LOADED;
|
||||
}
|
||||
else {
|
||||
entity = li.getImplementation();
|
||||
}
|
||||
sureFromUs = true;
|
||||
}
|
||||
else {
|
||||
entity = proxy;
|
||||
}
|
||||
|
||||
//we are instrumenting but we can't assume we are the only ones
|
||||
if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
|
||||
FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
|
||||
final boolean isInitialized = interceptor == null || interceptor.isInitialized( property );
|
||||
LoadState state;
|
||||
if (isInitialized && interceptor != null) {
|
||||
//property is loaded according to bytecode enhancement, but is it loaded as far as association?
|
||||
//it's ours, we can read
|
||||
state = isLoaded( get( entity, property ) );
|
||||
//it's ours so we know it's loaded
|
||||
if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
|
||||
}
|
||||
else if ( interceptor != null && (! isInitialized)) {
|
||||
state = LoadState.NOT_LOADED;
|
||||
}
|
||||
else if ( sureFromUs ) { //interceptor == null
|
||||
//property is loaded according to bytecode enhancement, but is it loaded as far as association?
|
||||
//it's ours, we can read
|
||||
state = isLoaded( get( entity, property ) );
|
||||
//it's ours so we know it's loaded
|
||||
if (state == LoadState.UNKNOWN) state = LoadState.LOADED;
|
||||
}
|
||||
else {
|
||||
state = LoadState.UNKNOWN;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
else {
|
||||
//can't do sureFromUs ? LoadState.LOADED : LoadState.UNKNOWN;
|
||||
//is that an association?
|
||||
return LoadState.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static LoadState isLoadedWithReference(Object proxy, String property) {
|
||||
//for sure we don't instrument and for sure it's not a lazy proxy
|
||||
Object object = get(proxy, property);
|
||||
return isLoaded( object );
|
||||
}
|
||||
|
||||
private static Object get(Object proxy, String property) {
|
||||
final Class<?> clazz = proxy.getClass();
|
||||
try {
|
||||
try {
|
||||
final Field field = clazz.getField( property );
|
||||
setAccessibility( field );
|
||||
return field.get( proxy );
|
||||
}
|
||||
catch ( NoSuchFieldException e ) {
|
||||
final Method method = getMethod( clazz, property );
|
||||
if (method != null) {
|
||||
setAccessibility( method );
|
||||
return method.invoke( proxy );
|
||||
}
|
||||
else {
|
||||
throw new PersistenceException( "Unable to find field or method: "
|
||||
+ clazz + "#"
|
||||
+ property);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IllegalAccessException e ) {
|
||||
throw new PersistenceException( "Unable to access field or method: "
|
||||
+ clazz + "#"
|
||||
+ property, e);
|
||||
}
|
||||
catch ( InvocationTargetException e ) {
|
||||
throw new PersistenceException( "Unable to access field or method: "
|
||||
+ clazz + "#"
|
||||
+ property, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the method with the specified name or <code>null</code> if it does not exist.
|
||||
*
|
||||
* @param clazz The class to check.
|
||||
* @param methodName The method name.
|
||||
*
|
||||
* @return Returns the method with the specified name or <code>null</code> if it does not exist.
|
||||
*/
|
||||
private static Method getMethod(Class<?> clazz, String methodName) {
|
||||
try {
|
||||
char string[] = methodName.toCharArray();
|
||||
string[0] = Character.toUpperCase( string[0] );
|
||||
methodName = new String( string );
|
||||
try {
|
||||
return clazz.getMethod( "get" + methodName );
|
||||
}
|
||||
catch ( NoSuchMethodException e ) {
|
||||
return clazz.getMethod( "is" + methodName );
|
||||
}
|
||||
}
|
||||
catch ( NoSuchMethodException e ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setAccessibility(Member member) {
|
||||
if ( !Modifier.isPublic( member.getModifiers() ) ) {
|
||||
//Sun's ease of use, sigh...
|
||||
( ( AccessibleObject ) member ).setAccessible( true );
|
||||
}
|
||||
}
|
||||
|
||||
public static LoadState isLoaded(Object o) {
|
||||
if ( o instanceof HibernateProxy ) {
|
||||
final boolean isInitialized = !( ( HibernateProxy ) o ).getHibernateLazyInitializer().isUninitialized();
|
||||
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
|
||||
}
|
||||
else if ( o instanceof PersistentCollection ) {
|
||||
final boolean isInitialized = ( ( PersistentCollection ) o ).wasInitialized();
|
||||
return isInitialized ? LoadState.LOADED : LoadState.NOT_LOADED;
|
||||
}
|
||||
else {
|
||||
return LoadState.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue