HHH-9837 - Remove reliance during annotation binding on org.hibernate.internal.util.ClassLoaderHelper
HHH-9841 - Redesign org.hibernate.property.PropertyAccessorFactory
This commit is contained in:
parent
53a8b18ca8
commit
9e063ffa25
|
@ -121,9 +121,10 @@ subprojects { subProject ->
|
||||||
|
|
||||||
// appropriately inject the common dependencies into each sub-project
|
// appropriately inject the common dependencies into each sub-project
|
||||||
dependencies {
|
dependencies {
|
||||||
compile( libraries.logging )
|
compile libraries.logging
|
||||||
|
|
||||||
|
provided libraries.logging_annotations
|
||||||
|
|
||||||
jbossLoggingTool( libraries.logging_annotations )
|
|
||||||
jbossLoggingTool( libraries.logging_processor )
|
jbossLoggingTool( libraries.logging_processor )
|
||||||
|
|
||||||
testCompile( libraries.junit )
|
testCompile( libraries.junit )
|
||||||
|
|
|
@ -3033,7 +3033,7 @@ public long getObjectVolume()</programlisting>
|
||||||
pair and access the field directly using reflection. You can specify
|
pair and access the field directly using reflection. You can specify
|
||||||
your own strategy for property access by naming a class that
|
your own strategy for property access by naming a class that
|
||||||
implements the interface
|
implements the interface
|
||||||
<literal>org.hibernate.property.PropertyAccessor</literal>.</para>
|
<literal>org.hibernate.property.access.spi.PropertyAccessStrategy</literal>.</para>
|
||||||
|
|
||||||
<para>A powerful feature is derived properties. These properties are
|
<para>A powerful feature is derived properties. These properties are
|
||||||
by definition read-only. The property value is computed at load time.
|
by definition read-only. The property value is computed at load time.
|
||||||
|
|
|
@ -4625,7 +4625,7 @@ msgstr ""
|
||||||
"<literal>access=\"field\"</literal>, Hibernate se saltará el par get/set y "
|
"<literal>access=\"field\"</literal>, Hibernate se saltará el par get/set y "
|
||||||
"accederá al campo directamente utilizando reflección. Puede especificar su "
|
"accederá al campo directamente utilizando reflección. Puede especificar su "
|
||||||
"propia estrategia de acceso a la propiedad mencionando una clase que "
|
"propia estrategia de acceso a la propiedad mencionando una clase que "
|
||||||
"implemente la interfaz <literal>org.hibernate.property.PropertyAccessor</"
|
"implemente la interfaz <literal>org.hibernate.property.access.spi.PropertyAccessStrategy</"
|
||||||
"literal>."
|
"literal>."
|
||||||
|
|
||||||
#. Tag: para
|
#. Tag: para
|
||||||
|
|
|
@ -3130,7 +3130,7 @@ msgstr ""
|
||||||
#. Tag: para
|
#. Tag: para
|
||||||
#: basic_mapping.xml:2250
|
#: basic_mapping.xml:2250
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "The <literal>access</literal> attribute allows you to control how Hibernate accesses the property at runtime. By default, Hibernate will call the property get/set pair. If you specify <literal>access=\"field\"</literal>, Hibernate will bypass the get/set pair and access the field directly using reflection. You can specify your own strategy for property access by naming a class that implements the interface <literal>org.hibernate.property.PropertyAccessor</literal>."
|
msgid "The <literal>access</literal> attribute allows you to control how Hibernate accesses the property at runtime. By default, Hibernate will call the property get/set pair. If you specify <literal>access=\"field\"</literal>, Hibernate will bypass the get/set pair and access the field directly using reflection. You can specify your own strategy for property access by naming a class that implements the interface <literal>org.hibernate.property.access.spi.PropertyAccessStrategy</literal>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Tag: para
|
#. Tag: para
|
||||||
|
|
|
@ -4695,7 +4695,7 @@ msgstr ""
|
||||||
"<literal>access=\"field\"</literal>, o Hibernate irá bipassar os metodos get/"
|
"<literal>access=\"field\"</literal>, o Hibernate irá bipassar os metodos get/"
|
||||||
"set, acessando o campo diretamente, usando reflexão. Você pode especificar "
|
"set, acessando o campo diretamente, usando reflexão. Você pode especificar "
|
||||||
"sua própria estratégia para acesso da propriedade criando uma classe que "
|
"sua própria estratégia para acesso da propriedade criando uma classe que "
|
||||||
"implemente a interface <literal>org.hibernate.property.PropertyAccessor</"
|
"implemente a interface <literal>org.hibernate.property.access.spi.PropertyAccessStrategy</"
|
||||||
"literal>."
|
"literal>."
|
||||||
|
|
||||||
#. Tag: para
|
#. Tag: para
|
||||||
|
|
|
@ -4638,7 +4638,7 @@ msgstr ""
|
||||||
"默认情况下,Hibernate 会使用属性的 get/set 方法对(pair)。如果你指明 "
|
"默认情况下,Hibernate 会使用属性的 get/set 方法对(pair)。如果你指明 "
|
||||||
"<literal>access=\"field\"</literal>,Hibernate 会忽略 get/set 方法对,直接使"
|
"<literal>access=\"field\"</literal>,Hibernate 会忽略 get/set 方法对,直接使"
|
||||||
"用反射来访问成员变量。你也可以指定你自己的策略,这就需要你自己实现 "
|
"用反射来访问成员变量。你也可以指定你自己的策略,这就需要你自己实现 "
|
||||||
"<literal>org.hibernate.property.PropertyAccessor</literal> 接口,再在 access "
|
"<literal>org.hibernate.property.access.spi.PropertyAccessStrategy</literal> 接口,再在 access "
|
||||||
"中设置你自定义策略类的名字。 "
|
"中设置你自定义策略类的名字。 "
|
||||||
|
|
||||||
#. Tag: para
|
#. Tag: para
|
||||||
|
|
|
@ -14,7 +14,7 @@ import static java.lang.annotation.ElementType.TYPE;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Names a {@link org.hibernate.property.PropertyAccessor} strategy to use.
|
* Names a persistent property access strategy ({@link org.hibernate.property.access.spi.PropertyAccessStrategy}) to use.
|
||||||
*
|
*
|
||||||
* Can be specified at either:<ul>
|
* Can be specified at either:<ul>
|
||||||
* <li>
|
* <li>
|
||||||
|
@ -26,10 +26,14 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* Should only be used to name custom {@link org.hibernate.property.PropertyAccessor}. For {@code property/field}
|
* Should only be used to name custom {@link org.hibernate.property.access.spi.PropertyAccessStrategy}. For
|
||||||
* access, the JPA {@link javax.persistence.Access} annotation should be preferred using the appropriate
|
* {@code property/field} access, the JPA {@link javax.persistence.Access} annotation should be preferred
|
||||||
* {@link javax.persistence.AccessType}. However, if this annotation is used with either {@code value="property"}
|
* using the appropriate {@link javax.persistence.AccessType}. However, if this annotation is used with
|
||||||
* or {@code value="field"}, it will act just as the corresponding usage of {@link javax.persistence.Access}.
|
* either {@code value="property"} or {@code value="field"}, it will act just as the corresponding usage
|
||||||
|
* of {@link javax.persistence.Access}.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.property.access.spi.PropertyAccessStrategy
|
||||||
|
* @see org.hibernate.property.access.spi.PropertyAccessStrategyResolver
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
|
@ -38,7 +42,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
public @interface AttributeAccessor {
|
public @interface AttributeAccessor {
|
||||||
/**
|
/**
|
||||||
* Names the {@link org.hibernate.property.PropertyAccessor} strategy.
|
* Names the {@link org.hibernate.property.access.spi.PropertyAccessStrategy} strategy.
|
||||||
*/
|
*/
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,10 +59,7 @@ public class MetadataSources implements Serializable {
|
||||||
|
|
||||||
private final ServiceRegistry serviceRegistry;
|
private final ServiceRegistry serviceRegistry;
|
||||||
|
|
||||||
// NOTE : The boolean here indicates whether or not to perform validation as we load XML documents.
|
private Binder mappingsBinder;
|
||||||
// Should we expose this setting? Disabling would speed up JAXP and JAXB at runtime, but potentially
|
|
||||||
// at the cost of less obvious errors when a document is not valid.
|
|
||||||
private Binder mappingsBinder = new MappingBinder( true );
|
|
||||||
|
|
||||||
private List<Binding> xmlBindings = new ArrayList<Binding>();
|
private List<Binding> xmlBindings = new ArrayList<Binding>();
|
||||||
private LinkedHashSet<Class<?>> annotatedClasses = new LinkedHashSet<Class<?>>();
|
private LinkedHashSet<Class<?>> annotatedClasses = new LinkedHashSet<Class<?>>();
|
||||||
|
@ -88,6 +85,11 @@ public class MetadataSources implements Serializable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
|
||||||
|
// NOTE : The boolean here indicates whether or not to perform validation as we load XML documents.
|
||||||
|
// Should we expose this setting? Disabling would speed up JAXP and JAXB at runtime, but potentially
|
||||||
|
// at the cost of less obvious errors when a document is not valid.
|
||||||
|
this.mappingsBinder = new MappingBinder( serviceRegistry.getService( ClassLoaderService.class ), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isExpectedServiceRegistryType(ServiceRegistry serviceRegistry) {
|
protected static boolean isExpectedServiceRegistryType(ServiceRegistry serviceRegistry) {
|
||||||
|
|
|
@ -53,9 +53,11 @@ public class JaxbCfgProcessor {
|
||||||
public static final String HIBERNATE_CONFIGURATION_URI = "http://www.hibernate.org/xsd/orm/cfg";
|
public static final String HIBERNATE_CONFIGURATION_URI = "http://www.hibernate.org/xsd/orm/cfg";
|
||||||
|
|
||||||
private final ClassLoaderService classLoaderService;
|
private final ClassLoaderService classLoaderService;
|
||||||
|
private final LocalXmlResourceResolver xmlResourceResolver;
|
||||||
|
|
||||||
public JaxbCfgProcessor(ClassLoaderService classLoaderService) {
|
public JaxbCfgProcessor(ClassLoaderService classLoaderService) {
|
||||||
this.classLoaderService = classLoaderService;
|
this.classLoaderService = classLoaderService;
|
||||||
|
this.xmlResourceResolver = new LocalXmlResourceResolver( classLoaderService );
|
||||||
}
|
}
|
||||||
|
|
||||||
public JaxbCfgHibernateConfiguration unmarshal(InputStream stream, Origin origin) {
|
public JaxbCfgHibernateConfiguration unmarshal(InputStream stream, Origin origin) {
|
||||||
|
@ -89,7 +91,7 @@ public class JaxbCfgProcessor {
|
||||||
@SuppressWarnings( { "UnnecessaryLocalVariable" })
|
@SuppressWarnings( { "UnnecessaryLocalVariable" })
|
||||||
private XMLInputFactory buildStaxFactory() {
|
private XMLInputFactory buildStaxFactory() {
|
||||||
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
|
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
|
||||||
staxFactory.setXMLResolver( LocalXmlResourceResolver.INSTANCE );
|
staxFactory.setXMLResolver( xmlResourceResolver );
|
||||||
return staxFactory;
|
return staxFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,10 @@ public class ClassLoaderAccessImpl implements ClassLoaderAccess {
|
||||||
this( tempClassLoader, serviceRegistry.getService( ClassLoaderService.class ) );
|
this( tempClassLoader, serviceRegistry.getService( ClassLoaderService.class ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassLoaderAccessImpl(ClassLoaderService classLoaderService) {
|
||||||
|
this( null, classLoaderService );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Class<?> classForName(String name) {
|
public Class<?> classForName(String name) {
|
||||||
|
|
|
@ -694,7 +694,7 @@ public class MetadataBuilderImpl implements MetadataBuilder, TypeContributions {
|
||||||
|
|
||||||
private ReflectionManager generateDefaultReflectionManager() {
|
private ReflectionManager generateDefaultReflectionManager() {
|
||||||
final JavaReflectionManager reflectionManager = new JavaReflectionManager();
|
final JavaReflectionManager reflectionManager = new JavaReflectionManager();
|
||||||
reflectionManager.setMetadataProvider( new JPAMetadataProvider() );
|
reflectionManager.setMetadataProvider( new JPAMetadataProvider( this ) );
|
||||||
reflectionManager.injectClassLoaderDelegate( getHcannClassLoaderDelegate() );
|
reflectionManager.injectClassLoaderDelegate( getHcannClassLoaderDelegate() );
|
||||||
return reflectionManager;
|
return reflectionManager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,7 +286,7 @@ public class MetadataBuildingProcess {
|
||||||
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
|
final EntityHierarchyBuilder hierarchyBuilder = new EntityHierarchyBuilder();
|
||||||
// final MappingBinder mappingBinder = new MappingBinder( true );
|
// final MappingBinder mappingBinder = new MappingBinder( true );
|
||||||
// We need to disable validation here. It seems Envers is not producing valid (according to schema) XML
|
// We need to disable validation here. It seems Envers is not producing valid (according to schema) XML
|
||||||
final MappingBinder mappingBinder = new MappingBinder( false );
|
final MappingBinder mappingBinder = new MappingBinder( classLoaderService, false );
|
||||||
for ( AdditionalJaxbMappingProducer producer : producers ) {
|
for ( AdditionalJaxbMappingProducer producer : producers ) {
|
||||||
log.tracef( "Calling AdditionalJaxbMappingProducer : %s", producer );
|
log.tracef( "Calling AdditionalJaxbMappingProducer : %s", producer );
|
||||||
Collection<MappingDocument> additionalMappings = producer.produceAdditionalMappings(
|
Collection<MappingDocument> additionalMappings = producer.produceAdditionalMappings(
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.boot.jaxb.internal.stax.BufferedXMLEventReader;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver;
|
import org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver;
|
||||||
import org.hibernate.boot.jaxb.spi.Binder;
|
import org.hibernate.boot.jaxb.spi.Binder;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -33,13 +34,15 @@ import org.jboss.logging.Logger;
|
||||||
public abstract class AbstractBinder implements Binder {
|
public abstract class AbstractBinder implements Binder {
|
||||||
private static final Logger log = Logger.getLogger( AbstractBinder.class );
|
private static final Logger log = Logger.getLogger( AbstractBinder.class );
|
||||||
|
|
||||||
|
private final LocalXmlResourceResolver xmlResourceResolver;
|
||||||
private final boolean validateXml;
|
private final boolean validateXml;
|
||||||
|
|
||||||
protected AbstractBinder() {
|
protected AbstractBinder(ClassLoaderService classLoaderService) {
|
||||||
this( true );
|
this( classLoaderService, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractBinder(boolean validateXml) {
|
protected AbstractBinder(ClassLoaderService classLoaderService, boolean validateXml) {
|
||||||
|
this.xmlResourceResolver = new LocalXmlResourceResolver( classLoaderService );
|
||||||
this.validateXml = validateXml;
|
this.validateXml = validateXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +124,7 @@ public abstract class AbstractBinder implements Binder {
|
||||||
@SuppressWarnings( { "UnnecessaryLocalVariable" })
|
@SuppressWarnings( { "UnnecessaryLocalVariable" })
|
||||||
private XMLInputFactory buildStaxFactory() {
|
private XMLInputFactory buildStaxFactory() {
|
||||||
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
|
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
|
||||||
staxFactory.setXMLResolver( LocalXmlResourceResolver.INSTANCE );
|
staxFactory.setXMLResolver( xmlResourceResolver );
|
||||||
return staxFactory;
|
return staxFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.boot.jaxb.internal.stax.HbmEventReader;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.JpaOrmXmlEventReader;
|
import org.hibernate.boot.jaxb.internal.stax.JpaOrmXmlEventReader;
|
||||||
import org.hibernate.boot.jaxb.internal.stax.LocalSchema;
|
import org.hibernate.boot.jaxb.internal.stax.LocalSchema;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -35,12 +36,12 @@ public class MappingBinder extends AbstractBinder {
|
||||||
|
|
||||||
private final XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance();
|
private final XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance();
|
||||||
|
|
||||||
public MappingBinder() {
|
public MappingBinder(ClassLoaderService classLoaderService) {
|
||||||
super();
|
super( classLoaderService );
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappingBinder(boolean validateXml) {
|
public MappingBinder(ClassLoaderService classLoaderService, boolean validateXml) {
|
||||||
super( validateXml );
|
super( classLoaderService, validateXml );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,9 +11,9 @@ import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ConfigHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -21,10 +21,14 @@ import org.hibernate.internal.util.ConfigHelper;
|
||||||
public class LocalXmlResourceResolver implements javax.xml.stream.XMLResolver {
|
public class LocalXmlResourceResolver implements javax.xml.stream.XMLResolver {
|
||||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( LocalXmlResourceResolver.class );
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( LocalXmlResourceResolver.class );
|
||||||
|
|
||||||
public static final LocalXmlResourceResolver INSTANCE = new LocalXmlResourceResolver();
|
|
||||||
|
|
||||||
public static final String CLASSPATH_EXTENSION_URL_BASE = "classpath://";
|
public static final String CLASSPATH_EXTENSION_URL_BASE = "classpath://";
|
||||||
|
|
||||||
|
private final ClassLoaderService classLoaderService;
|
||||||
|
|
||||||
|
public LocalXmlResourceResolver(ClassLoaderService classLoaderService) {
|
||||||
|
this.classLoaderService = classLoaderService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
|
public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
|
||||||
log.tracef( "In resolveEntity(%s, %s, %s, %s)", publicID, systemID, baseURI, namespace );
|
log.tracef( "In resolveEntity(%s, %s, %s, %s)", publicID, systemID, baseURI, namespace );
|
||||||
|
@ -115,7 +119,7 @@ public class LocalXmlResourceResolver implements javax.xml.stream.XMLResolver {
|
||||||
|
|
||||||
private InputStream resolveInLocalNamespace(String path) {
|
private InputStream resolveInLocalNamespace(String path) {
|
||||||
try {
|
try {
|
||||||
return ConfigHelper.getUserResourceAsStream( path );
|
return classLoaderService.locateResourceStream( path );
|
||||||
}
|
}
|
||||||
catch ( Throwable t ) {
|
catch ( Throwable t ) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -152,6 +152,8 @@ public class ModelBinder {
|
||||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( ModelBinder.class );
|
private static final CoreMessageLogger log = CoreLogging.messageLogger( ModelBinder.class );
|
||||||
private static final boolean debugEnabled = log.isDebugEnabled();
|
private static final boolean debugEnabled = log.isDebugEnabled();
|
||||||
|
|
||||||
|
private final MetadataBuildingContext metadataBuildingContext;
|
||||||
|
|
||||||
private final Database database;
|
private final Database database;
|
||||||
private final ObjectNameNormalizer objectNameNormalizer;
|
private final ObjectNameNormalizer objectNameNormalizer;
|
||||||
private final ImplicitNamingStrategy implicitNamingStrategy;
|
private final ImplicitNamingStrategy implicitNamingStrategy;
|
||||||
|
@ -162,6 +164,8 @@ public class ModelBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModelBinder(final MetadataBuildingContext context) {
|
public ModelBinder(final MetadataBuildingContext context) {
|
||||||
|
this.metadataBuildingContext = context;
|
||||||
|
|
||||||
this.database = context.getMetadataCollector().getDatabase();
|
this.database = context.getMetadataCollector().getDatabase();
|
||||||
this.objectNameNormalizer = new ObjectNameNormalizer() {
|
this.objectNameNormalizer = new ObjectNameNormalizer() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,7 +181,7 @@ public class ModelBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindEntityHierarchy(EntityHierarchySourceImpl hierarchySource) {
|
public void bindEntityHierarchy(EntityHierarchySourceImpl hierarchySource) {
|
||||||
final RootClass rootEntityDescriptor = new RootClass();
|
final RootClass rootEntityDescriptor = new RootClass( metadataBuildingContext );
|
||||||
bindRootEntity( hierarchySource, rootEntityDescriptor );
|
bindRootEntity( hierarchySource, rootEntityDescriptor );
|
||||||
hierarchySource.getRoot()
|
hierarchySource.getRoot()
|
||||||
.getLocalMetadataBuildingContext()
|
.getLocalMetadataBuildingContext()
|
||||||
|
@ -503,7 +507,7 @@ public class ModelBinder {
|
||||||
AbstractEntitySourceImpl entitySource,
|
AbstractEntitySourceImpl entitySource,
|
||||||
PersistentClass superEntityDescriptor) {
|
PersistentClass superEntityDescriptor) {
|
||||||
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
||||||
final SingleTableSubclass subEntityDescriptor = new SingleTableSubclass( superEntityDescriptor );
|
final SingleTableSubclass subEntityDescriptor = new SingleTableSubclass( superEntityDescriptor, metadataBuildingContext );
|
||||||
bindDiscriminatorSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor );
|
bindDiscriminatorSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor );
|
||||||
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
||||||
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
||||||
|
@ -561,7 +565,7 @@ public class ModelBinder {
|
||||||
AbstractEntitySourceImpl entitySource,
|
AbstractEntitySourceImpl entitySource,
|
||||||
PersistentClass superEntityDescriptor) {
|
PersistentClass superEntityDescriptor) {
|
||||||
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
||||||
final JoinedSubclass subEntityDescriptor = new JoinedSubclass( superEntityDescriptor );
|
final JoinedSubclass subEntityDescriptor = new JoinedSubclass( superEntityDescriptor, metadataBuildingContext );
|
||||||
bindJoinedSubclassEntity( (JoinedSubclassEntitySourceImpl) subType, subEntityDescriptor );
|
bindJoinedSubclassEntity( (JoinedSubclassEntitySourceImpl) subType, subEntityDescriptor );
|
||||||
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
||||||
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
||||||
|
@ -637,7 +641,7 @@ public class ModelBinder {
|
||||||
EntitySource entitySource,
|
EntitySource entitySource,
|
||||||
PersistentClass superEntityDescriptor) {
|
PersistentClass superEntityDescriptor) {
|
||||||
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
for ( IdentifiableTypeSource subType : entitySource.getSubTypes() ) {
|
||||||
final UnionSubclass subEntityDescriptor = new UnionSubclass( superEntityDescriptor );
|
final UnionSubclass subEntityDescriptor = new UnionSubclass( superEntityDescriptor, metadataBuildingContext );
|
||||||
bindUnionSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor );
|
bindUnionSubclassEntity( (SubclassEntitySourceImpl) subType, subEntityDescriptor );
|
||||||
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
superEntityDescriptor.addSubclass( subEntityDescriptor );
|
||||||
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
entitySource.getLocalMetadataBuildingContext().getMetadataCollector().addEntityBinding( subEntityDescriptor );
|
||||||
|
|
|
@ -56,7 +56,7 @@ public interface AttributeSource extends ToolingHintContextContainer {
|
||||||
*
|
*
|
||||||
* @return The property accessor style for this attribute.
|
* @return The property accessor style for this attribute.
|
||||||
*
|
*
|
||||||
* @see org.hibernate.property.PropertyAccessor
|
* @see org.hibernate.property.access.spi.PropertyAccessStrategy
|
||||||
*/
|
*/
|
||||||
public String getPropertyAccessorName();
|
public String getPropertyAccessorName();
|
||||||
|
|
||||||
|
|
|
@ -326,6 +326,10 @@ public class StandardServiceRegistryBuilder {
|
||||||
* @param serviceRegistry The registry to be closed.
|
* @param serviceRegistry The registry to be closed.
|
||||||
*/
|
*/
|
||||||
public static void destroy(ServiceRegistry serviceRegistry) {
|
public static void destroy(ServiceRegistry serviceRegistry) {
|
||||||
|
if ( serviceRegistry == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
( (StandardServiceRegistryImpl) serviceRegistry ).destroy();
|
( (StandardServiceRegistryImpl) serviceRegistry ).destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.boot.registry.classloading.internal;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -26,7 +28,6 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ClassLoaderHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard implementation of the service for interacting with class loaders
|
* Standard implementation of the service for interacting with class loaders
|
||||||
|
@ -149,7 +150,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
|
|
||||||
private static ClassLoader locateTCCL() {
|
private static ClassLoader locateTCCL() {
|
||||||
try {
|
try {
|
||||||
return ClassLoaderHelper.getContextClassLoader();
|
return Thread.currentThread().getContextClassLoader();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -321,6 +322,20 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> T generateProxy(InvocationHandler handler, Class... interfaces) {
|
||||||
|
return (T) Proxy.newProxyInstance(
|
||||||
|
getAggregatedClassLoader(),
|
||||||
|
interfaces,
|
||||||
|
handler
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T workWithClassLoader(Work<T> work) {
|
||||||
|
return work.doWork( getAggregatedClassLoader() );
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getAggregatedClassLoader() {
|
private ClassLoader getAggregatedClassLoader() {
|
||||||
final ClassLoader aggregated = this.aggregatedClassLoader;
|
final ClassLoader aggregated = this.aggregatedClassLoader;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.boot.registry.classloading.spi;
|
package org.hibernate.boot.registry.classloading.spi;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -71,4 +72,12 @@ public interface ClassLoaderService extends Service, Stoppable {
|
||||||
* @return The ordered set of discovered services.
|
* @return The ordered set of discovered services.
|
||||||
*/
|
*/
|
||||||
public <S> Collection<S> loadJavaServices(Class<S> serviceContract);
|
public <S> Collection<S> loadJavaServices(Class<S> serviceContract);
|
||||||
|
|
||||||
|
<T> T generateProxy(InvocationHandler handler, Class... interfaces);
|
||||||
|
|
||||||
|
interface Work<T> {
|
||||||
|
T doWork(ClassLoader classLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
<T> T workWithClassLoader(Work<T> work);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.boot.spi;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ClassLoaderAccess implementation based on delegation
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public abstract class ClassLoaderAccessDelegateImpl implements ClassLoaderAccess {
|
||||||
|
protected abstract ClassLoaderAccess getDelegate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Class<T> classForName(String name) {
|
||||||
|
return getDelegate().classForName( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL locateResource(String resourceName) {
|
||||||
|
return getDelegate().locateResource( resourceName );
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,12 +95,12 @@ public interface MappingDefaults {
|
||||||
public String getImplicitCascadeStyleName();
|
public String getImplicitCascadeStyleName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies the default {@link org.hibernate.property.PropertyAccessor} name to use if none specified in the
|
* Identifies the default {@link org.hibernate.property.access.spi.PropertyAccessStrategy} name to use if none specified in the
|
||||||
* mapping.
|
* mapping.
|
||||||
*
|
*
|
||||||
* @return The implicit property accessor name
|
* @return The implicit property accessor name
|
||||||
*
|
*
|
||||||
* @see org.hibernate.property.PropertyAccessorFactory
|
* @see org.hibernate.property.access.spi.PropertyAccessStrategy
|
||||||
*/
|
*/
|
||||||
public String getImplicitPropertyAccessorName();
|
public String getImplicitPropertyAccessorName();
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,7 @@ import org.hibernate.cfg.annotations.TableBinder;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.engine.spi.FilterDefinition;
|
import org.hibernate.engine.spi.FilterDefinition;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
|
@ -165,34 +166,31 @@ import org.hibernate.mapping.Subclass;
|
||||||
import org.hibernate.mapping.ToOne;
|
import org.hibernate.mapping.ToOne;
|
||||||
import org.hibernate.mapping.UnionSubclass;
|
import org.hibernate.mapping.UnionSubclass;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSR 175 annotation binder which reads the annotations from classes, applies the
|
* JSR 175 annotation binder which reads the annotations from classes, applies the
|
||||||
* principles of the EJB3 spec and produces the Hibernate configuration-time metamodel
|
* principles of the EJB3 spec and produces the Hibernate configuration-time metamodel
|
||||||
* (the classes in the {@code org.hibernate.mapping} package)
|
* (the classes in the {@code org.hibernate.mapping} package)
|
||||||
|
* <p/>
|
||||||
|
* Some design description
|
||||||
|
* I tried to remove any link to annotation except from the 2 first level of
|
||||||
|
* method call.
|
||||||
|
* It'll enable to:
|
||||||
|
* - facilitate annotation overriding
|
||||||
|
* - mutualize one day xml and annotation binder (probably a dream though)
|
||||||
|
* - split this huge class in smaller mapping oriented classes
|
||||||
|
*
|
||||||
|
* bindSomething usually create the mapping container and is accessed by one of the 2 first level method
|
||||||
|
* makeSomething usually create the mapping container and is accessed by bindSomething[else]
|
||||||
|
* fillSomething take the container into parameter and fill it.
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final class AnnotationBinder {
|
public final class AnnotationBinder {
|
||||||
|
private static final CoreMessageLogger LOG = messageLogger( AnnotationBinder.class );
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, AnnotationBinder.class.getName() );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some design description
|
|
||||||
* I tried to remove any link to annotation except from the 2 first level of
|
|
||||||
* method call.
|
|
||||||
* It'll enable to:
|
|
||||||
* - facilitate annotation overriding
|
|
||||||
* - mutualize one day xml and annotation binder (probably a dream though)
|
|
||||||
* - split this huge class in smaller mapping oriented classes
|
|
||||||
*
|
|
||||||
* bindSomething usually create the mapping container and is accessed by one of the 2 first level method
|
|
||||||
* makeSomething usually create the mapping container and is accessed by bindSomething[else]
|
|
||||||
* fillSomething take the container into parameter and fill it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private AnnotationBinder() {
|
private AnnotationBinder() {
|
||||||
}
|
}
|
||||||
|
@ -518,7 +516,7 @@ public final class AnnotationBinder {
|
||||||
inheritanceState
|
inheritanceState
|
||||||
);
|
);
|
||||||
|
|
||||||
PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity );
|
PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity, context );
|
||||||
Entity entityAnn = clazzToProcess.getAnnotation( Entity.class );
|
Entity entityAnn = clazzToProcess.getAnnotation( Entity.class );
|
||||||
org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
|
org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
|
||||||
org.hibernate.annotations.Entity.class
|
org.hibernate.annotations.Entity.class
|
||||||
|
@ -1176,26 +1174,26 @@ public final class AnnotationBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PersistentClass makePersistentClass(InheritanceState inheritanceState, PersistentClass superEntity) {
|
private static PersistentClass makePersistentClass(
|
||||||
|
InheritanceState inheritanceState,
|
||||||
|
PersistentClass superEntity,
|
||||||
|
MetadataBuildingContext metadataBuildingContext) {
|
||||||
//we now know what kind of persistent entity it is
|
//we now know what kind of persistent entity it is
|
||||||
PersistentClass persistentClass;
|
|
||||||
//create persistent class
|
|
||||||
if ( !inheritanceState.hasParents() ) {
|
if ( !inheritanceState.hasParents() ) {
|
||||||
persistentClass = new RootClass();
|
return new RootClass( metadataBuildingContext );
|
||||||
}
|
}
|
||||||
else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
|
else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
|
||||||
persistentClass = new SingleTableSubclass( superEntity );
|
return new SingleTableSubclass( superEntity, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
|
else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
|
||||||
persistentClass = new JoinedSubclass( superEntity );
|
return new JoinedSubclass( superEntity, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
|
else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
|
||||||
persistentClass = new UnionSubclass( superEntity );
|
return new UnionSubclass( superEntity, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new AssertionFailure( "Unknown inheritance type: " + inheritanceState.getType() );
|
throw new AssertionFailure( "Unknown inheritance type: " + inheritanceState.getType() );
|
||||||
}
|
}
|
||||||
return persistentClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Ejb3JoinColumn[] makeInheritanceJoinColumns(
|
private static Ejb3JoinColumn[] makeInheritanceJoinColumns(
|
||||||
|
|
|
@ -6,6 +6,22 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cfg.annotations;
|
package org.hibernate.cfg.annotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.persistence.Access;
|
||||||
|
import javax.persistence.ConstraintMode;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.JoinTable;
|
||||||
|
import javax.persistence.NamedEntityGraph;
|
||||||
|
import javax.persistence.NamedEntityGraphs;
|
||||||
|
import javax.persistence.PrimaryKeyJoinColumn;
|
||||||
|
import javax.persistence.SecondaryTable;
|
||||||
|
import javax.persistence.SecondaryTables;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
@ -45,6 +61,7 @@ import org.hibernate.boot.model.naming.EntityNaming;
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
import org.hibernate.boot.model.naming.ImplicitEntityNameSource;
|
import org.hibernate.boot.model.naming.ImplicitEntityNameSource;
|
||||||
import org.hibernate.boot.model.naming.NamingStrategyHelper;
|
import org.hibernate.boot.model.naming.NamingStrategyHelper;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
import org.hibernate.boot.spi.InFlightMetadataCollector;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.cfg.AccessType;
|
import org.hibernate.cfg.AccessType;
|
||||||
|
@ -59,7 +76,6 @@ import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.FilterDefinition;
|
import org.hibernate.engine.spi.FilterDefinition;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.mapping.DependantValue;
|
import org.hibernate.mapping.DependantValue;
|
||||||
import org.hibernate.mapping.Join;
|
import org.hibernate.mapping.Join;
|
||||||
|
@ -70,23 +86,8 @@ import org.hibernate.mapping.SingleTableSubclass;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.TableOwner;
|
import org.hibernate.mapping.TableOwner;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import javax.persistence.Access;
|
import org.jboss.logging.Logger;
|
||||||
import javax.persistence.ConstraintMode;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.JoinTable;
|
|
||||||
import javax.persistence.NamedEntityGraph;
|
|
||||||
import javax.persistence.NamedEntityGraphs;
|
|
||||||
import javax.persistence.PrimaryKeyJoinColumn;
|
|
||||||
import javax.persistence.SecondaryTable;
|
|
||||||
import javax.persistence.SecondaryTables;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.hibernate.cfg.BinderHelper.toAliasEntityMap;
|
import static org.hibernate.cfg.BinderHelper.toAliasEntityMap;
|
||||||
import static org.hibernate.cfg.BinderHelper.toAliasTableMap;
|
import static org.hibernate.cfg.BinderHelper.toAliasTableMap;
|
||||||
|
@ -297,10 +298,10 @@ public class EntityBinder {
|
||||||
org.hibernate.annotations.Entity entityAnn = annotatedClass.getAnnotation( org.hibernate.annotations.Entity.class );
|
org.hibernate.annotations.Entity entityAnn = annotatedClass.getAnnotation( org.hibernate.annotations.Entity.class );
|
||||||
if ( entityAnn != null && !BinderHelper.isEmptyAnnotationValue( entityAnn.persister() ) ) {
|
if ( entityAnn != null && !BinderHelper.isEmptyAnnotationValue( entityAnn.persister() ) ) {
|
||||||
try {
|
try {
|
||||||
persister = ReflectHelper.classForName( entityAnn.persister() );
|
persister = context.getClassLoaderAccess().classForName( entityAnn.persister() );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassLoadingException e) {
|
||||||
throw new AnnotationException( "Could not find persister class: " + persister );
|
throw new AnnotationException( "Could not find persister class: " + entityAnn.persister(), e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.cfg.annotations.reflection;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ClassLoaderAccess implementation based on lazy access to {@link MetadataBuildingOptions}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ClassLoaderAccessLazyImpl implements ClassLoaderAccess {
|
||||||
|
private final MetadataBuildingOptions metadataBuildingOptions;
|
||||||
|
|
||||||
|
public ClassLoaderAccessLazyImpl(MetadataBuildingOptions metadataBuildingOptions) {
|
||||||
|
this.metadataBuildingOptions = metadataBuildingOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Class<T> classForName(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL locateResource(String resourceName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,9 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.cfg.annotations.reflection;
|
package org.hibernate.cfg.annotations.reflection;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -25,7 +22,12 @@ import javax.persistence.TableGenerator;
|
||||||
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
||||||
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
||||||
import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
|
import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.boot.internal.ClassLoaderAccessImpl;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccessDelegateImpl;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingOptions;
|
||||||
|
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
@ -35,25 +37,43 @@ import org.dom4j.Element;
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
public class JPAMetadataProvider implements MetadataProvider {
|
||||||
private transient MetadataProvider delegate = new JavaMetadataProvider();
|
|
||||||
private transient Map<Object, Object> defaults;
|
private final MetadataProvider delegate = new JavaMetadataProvider();
|
||||||
private transient Map<AnnotatedElement, AnnotationReader> cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
|
|
||||||
|
private final ClassLoaderAccess classLoaderAccess;
|
||||||
|
private final XMLContext xmlContext;
|
||||||
|
|
||||||
|
private Map<Object, Object> defaults;
|
||||||
|
private Map<AnnotatedElement, AnnotationReader> cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
|
||||||
|
|
||||||
|
public JPAMetadataProvider(final MetadataBuildingOptions metadataBuildingOptions) {
|
||||||
|
classLoaderAccess = new ClassLoaderAccessDelegateImpl() {
|
||||||
|
ClassLoaderAccess delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ClassLoaderAccess getDelegate() {
|
||||||
|
if ( delegate == null ) {
|
||||||
|
delegate = new ClassLoaderAccessImpl(
|
||||||
|
metadataBuildingOptions.getTempClassLoader(),
|
||||||
|
metadataBuildingOptions.getServiceRegistry().getService( ClassLoaderService.class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
xmlContext = new XMLContext( classLoaderAccess );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//all of the above can be safely rebuilt from XMLContext: only XMLContext this object is serialized
|
//all of the above can be safely rebuilt from XMLContext: only XMLContext this object is serialized
|
||||||
private XMLContext xmlContext = new XMLContext();
|
|
||||||
|
|
||||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
|
||||||
ois.defaultReadObject();
|
|
||||||
delegate = new JavaMetadataProvider();
|
|
||||||
cache = new HashMap<AnnotatedElement, AnnotationReader>(100);
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
|
public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
|
||||||
AnnotationReader reader = cache.get( annotatedElement );
|
AnnotationReader reader = cache.get( annotatedElement );
|
||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
if ( xmlContext.hasContext() ) {
|
if ( xmlContext.hasContext() ) {
|
||||||
reader = new JPAOverriddenAnnotationReader( annotatedElement, xmlContext );
|
reader = new JPAOverriddenAnnotationReader( annotatedElement, xmlContext, classLoaderAccess );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reader = delegate.getAnnotationReader( annotatedElement );
|
reader = delegate.getAnnotationReader( annotatedElement );
|
||||||
|
@ -74,9 +94,9 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||||
List<Class> entityListeners = new ArrayList<Class>();
|
List<Class> entityListeners = new ArrayList<Class>();
|
||||||
for ( String className : xmlContext.getDefaultEntityListeners() ) {
|
for ( String className : xmlContext.getDefaultEntityListeners() ) {
|
||||||
try {
|
try {
|
||||||
entityListeners.add( ReflectHelper.classForName( className, this.getClass() ) );
|
entityListeners.add( classLoaderAccess.classForName( className ) );
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new IllegalStateException( "Default entity listener class not found: " + className );
|
throw new IllegalStateException( "Default entity listener class not found: " + className );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +133,10 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||||
defaults.put( NamedQuery.class, namedQueries );
|
defaults.put( NamedQuery.class, namedQueries );
|
||||||
}
|
}
|
||||||
List<NamedQuery> currentNamedQueries = JPAOverriddenAnnotationReader.buildNamedQueries(
|
List<NamedQuery> currentNamedQueries = JPAOverriddenAnnotationReader.buildNamedQueries(
|
||||||
element, false, xmlDefaults
|
element,
|
||||||
|
false,
|
||||||
|
xmlDefaults,
|
||||||
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
namedQueries.addAll( currentNamedQueries );
|
namedQueries.addAll( currentNamedQueries );
|
||||||
|
|
||||||
|
@ -123,7 +146,10 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||||
defaults.put( NamedNativeQuery.class, namedNativeQueries );
|
defaults.put( NamedNativeQuery.class, namedNativeQueries );
|
||||||
}
|
}
|
||||||
List<NamedNativeQuery> currentNamedNativeQueries = JPAOverriddenAnnotationReader.buildNamedQueries(
|
List<NamedNativeQuery> currentNamedNativeQueries = JPAOverriddenAnnotationReader.buildNamedQueries(
|
||||||
element, true, xmlDefaults
|
element,
|
||||||
|
true,
|
||||||
|
xmlDefaults,
|
||||||
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
namedNativeQueries.addAll( currentNamedNativeQueries );
|
namedNativeQueries.addAll( currentNamedNativeQueries );
|
||||||
|
|
||||||
|
@ -135,7 +161,9 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||||
defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
|
defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
|
||||||
}
|
}
|
||||||
List<SqlResultSetMapping> currentSqlResultSetMappings = JPAOverriddenAnnotationReader.buildSqlResultsetMappings(
|
List<SqlResultSetMapping> currentSqlResultSetMappings = JPAOverriddenAnnotationReader.buildSqlResultsetMappings(
|
||||||
element, xmlDefaults
|
element,
|
||||||
|
xmlDefaults,
|
||||||
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
sqlResultSetMappings.addAll( currentSqlResultSetMappings );
|
sqlResultSetMappings.addAll( currentSqlResultSetMappings );
|
||||||
|
|
||||||
|
@ -145,7 +173,9 @@ public class JPAMetadataProvider implements MetadataProvider, Serializable {
|
||||||
defaults.put( NamedStoredProcedureQuery.class, namedStoredProcedureQueries );
|
defaults.put( NamedStoredProcedureQuery.class, namedStoredProcedureQueries );
|
||||||
}
|
}
|
||||||
List<NamedStoredProcedureQuery> currentNamedStoredProcedureQueries = JPAOverriddenAnnotationReader.buildNamedStoreProcedureQueries(
|
List<NamedStoredProcedureQuery> currentNamedStoredProcedureQueries = JPAOverriddenAnnotationReader.buildNamedStoreProcedureQueries(
|
||||||
element, xmlDefaults
|
element,
|
||||||
|
xmlDefaults,
|
||||||
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
namedStoredProcedureQueries.addAll( currentNamedStoredProcedureQueries );
|
namedStoredProcedureQueries.addAll( currentNamedStoredProcedureQueries );
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,9 +122,10 @@ import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
|
||||||
import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
|
import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
|
||||||
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionUtil;
|
import org.hibernate.annotations.common.reflection.ReflectionUtil;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
|
@ -236,6 +237,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private XMLContext xmlContext;
|
private XMLContext xmlContext;
|
||||||
|
private final ClassLoaderAccess classLoaderAccess;
|
||||||
private final AnnotatedElement element;
|
private final AnnotatedElement element;
|
||||||
private String className;
|
private String className;
|
||||||
private String propertyName;
|
private String propertyName;
|
||||||
|
@ -245,9 +247,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
private transient List<Element> elementsForProperty;
|
private transient List<Element> elementsForProperty;
|
||||||
private AccessibleObject mirroredAttribute;
|
private AccessibleObject mirroredAttribute;
|
||||||
|
|
||||||
public JPAOverriddenAnnotationReader(AnnotatedElement el, XMLContext xmlContext) {
|
public JPAOverriddenAnnotationReader(AnnotatedElement el, XMLContext xmlContext, ClassLoaderAccess classLoaderAccess) {
|
||||||
this.element = el;
|
this.element = el;
|
||||||
this.xmlContext = xmlContext;
|
this.xmlContext = xmlContext;
|
||||||
|
this.classLoaderAccess = classLoaderAccess;
|
||||||
|
|
||||||
if ( el instanceof Class ) {
|
if ( el instanceof Class ) {
|
||||||
Class clazz = (Class) el;
|
Class clazz = (Class) el;
|
||||||
className = clazz.getName();
|
className = clazz.getName();
|
||||||
|
@ -505,10 +509,10 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
defaults
|
defaults
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
final Class converterClass = ReflectHelper.classForName( converterClassName, this.getClass() );
|
final Class converterClass = classLoaderAccess.classForName( converterClassName );
|
||||||
convertAnnotationDescriptor.setValue( "converter", converterClass );
|
convertAnnotationDescriptor.setValue( "converter", converterClass );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassLoadingException e) {
|
||||||
throw new AnnotationException( "Unable to find specified converter class id-class: " + converterClassName, e );
|
throw new AnnotationException( "Unable to find specified converter class id-class: " + converterClassName, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,9 +568,9 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
private void checkForOrphanProperties(Element tree) {
|
private void checkForOrphanProperties(Element tree) {
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName( className, this.getClass() );
|
clazz = classLoaderAccess.classForName( className );
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
return; //a primitive type most likely
|
return; //a primitive type most likely
|
||||||
}
|
}
|
||||||
Element element = tree != null ? tree.element( "attributes" ) : null;
|
Element element = tree != null ? tree.element( "attributes" ) : null;
|
||||||
|
@ -708,13 +712,12 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
String className = subelement.attributeValue( "class" );
|
String className = subelement.attributeValue( "class" );
|
||||||
try {
|
try {
|
||||||
entityListenerClasses.add(
|
entityListenerClasses.add(
|
||||||
ReflectHelper.classForName(
|
classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( className, defaults ),
|
XMLContext.buildSafeClassName( className, defaults )
|
||||||
this.getClass()
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException(
|
throw new AnnotationException(
|
||||||
"Unable to find " + element.getPath() + ".class: " + className, e
|
"Unable to find " + element.getPath() + ".class: " + className, e
|
||||||
);
|
);
|
||||||
|
@ -1077,11 +1080,9 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
if ( className != null ) {
|
if ( className != null ) {
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName( XMLContext.buildSafeClassName( className, defaults ) );
|
||||||
XMLContext.buildSafeClassName( className, defaults ), this.getClass()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException(
|
throw new AnnotationException(
|
||||||
"Unable to find " + element.getPath() + " " + nodeName + ": " + className, e
|
"Unable to find " + element.getPath() + " " + nodeName + ": " + className, e
|
||||||
);
|
);
|
||||||
|
@ -1178,12 +1179,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
if ( StringHelper.isNotEmpty( mapKeyClassName ) ) {
|
if ( StringHelper.isNotEmpty( mapKeyClassName ) ) {
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( mapKeyClassName, defaults ),
|
XMLContext.buildSafeClassName( mapKeyClassName, defaults )
|
||||||
this.getClass()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException(
|
throw new AnnotationException(
|
||||||
"Unable to find " + element.getPath() + " " + nodeName + ": " + mapKeyClassName, e
|
"Unable to find " + element.getPath() + " " + nodeName + ": " + mapKeyClassName, e
|
||||||
);
|
);
|
||||||
|
@ -1862,7 +1862,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SqlResultSetMappings getSqlResultSetMappings(Element tree, XMLContext.Default defaults) {
|
private SqlResultSetMappings getSqlResultSetMappings(Element tree, XMLContext.Default defaults) {
|
||||||
List<SqlResultSetMapping> results = buildSqlResultsetMappings( tree, defaults );
|
List<SqlResultSetMapping> results = buildSqlResultsetMappings( tree, defaults, classLoaderAccess );
|
||||||
if ( defaults.canUseJavaAnnotations() ) {
|
if ( defaults.canUseJavaAnnotations() ) {
|
||||||
SqlResultSetMapping annotation = getPhysicalAnnotation( SqlResultSetMapping.class );
|
SqlResultSetMapping annotation = getPhysicalAnnotation( SqlResultSetMapping.class );
|
||||||
addSqlResultsetMappingIfNeeded( annotation, results );
|
addSqlResultsetMappingIfNeeded( annotation, results );
|
||||||
|
@ -1883,7 +1883,10 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<NamedEntityGraph> buildNamedEntityGraph(Element element, XMLContext.Default defaults) {
|
public static List<NamedEntityGraph> buildNamedEntityGraph(
|
||||||
|
Element element,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
if ( element == null ) {
|
if ( element == null ) {
|
||||||
return new ArrayList<NamedEntityGraph>();
|
return new ArrayList<NamedEntityGraph>();
|
||||||
}
|
}
|
||||||
|
@ -1896,16 +1899,20 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
bindNamedAttributeNodes( subElement, ann );
|
bindNamedAttributeNodes( subElement, ann );
|
||||||
|
|
||||||
List<Element> subgraphNodes = subElement.elements( "subgraph" );
|
List<Element> subgraphNodes = subElement.elements( "subgraph" );
|
||||||
bindNamedSubgraph( defaults, ann, subgraphNodes );
|
bindNamedSubgraph( defaults, ann, subgraphNodes, classLoaderAccess );
|
||||||
List<Element> subclassSubgraphNodes = subElement.elements( "subclass-subgraph" );
|
List<Element> subclassSubgraphNodes = subElement.elements( "subclass-subgraph" );
|
||||||
bindNamedSubgraph( defaults, ann, subclassSubgraphNodes );
|
bindNamedSubgraph( defaults, ann, subclassSubgraphNodes, classLoaderAccess );
|
||||||
namedEntityGraphList.add( (NamedEntityGraph) AnnotationFactory.create( ann ) );
|
namedEntityGraphList.add( (NamedEntityGraph) AnnotationFactory.create( ann ) );
|
||||||
}
|
}
|
||||||
//TODO
|
//TODO
|
||||||
return namedEntityGraphList;
|
return namedEntityGraphList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void bindNamedSubgraph(XMLContext.Default defaults, AnnotationDescriptor ann, List<Element> subgraphNodes) {
|
private static void bindNamedSubgraph(
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
AnnotationDescriptor ann,
|
||||||
|
List<Element> subgraphNodes,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
List<NamedSubgraph> annSubgraphNodes = new ArrayList<NamedSubgraph>( );
|
List<NamedSubgraph> annSubgraphNodes = new ArrayList<NamedSubgraph>( );
|
||||||
for(Element subgraphNode : subgraphNodes){
|
for(Element subgraphNode : subgraphNodes){
|
||||||
AnnotationDescriptor annSubgraphNode = new AnnotationDescriptor( NamedSubgraph.class );
|
AnnotationDescriptor annSubgraphNode = new AnnotationDescriptor( NamedSubgraph.class );
|
||||||
|
@ -1913,12 +1920,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
String clazzName = subgraphNode.attributeValue( "class" );
|
String clazzName = subgraphNode.attributeValue( "class" );
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
XMLContext.buildSafeClassName( clazzName, defaults )
|
||||||
JPAOverriddenAnnotationReader.class
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||||
}
|
}
|
||||||
annSubgraphNode.setValue( "type", clazz );
|
annSubgraphNode.setValue( "type", clazz );
|
||||||
|
@ -1941,7 +1947,10 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
ann.setValue( "attributeNodes", annNamedAttributeNodes.toArray( new NamedAttributeNode[annNamedAttributeNodes.size()] ) );
|
ann.setValue( "attributeNodes", annNamedAttributeNodes.toArray( new NamedAttributeNode[annNamedAttributeNodes.size()] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<NamedStoredProcedureQuery> buildNamedStoreProcedureQueries(Element element, XMLContext.Default defaults) {
|
public static List<NamedStoredProcedureQuery> buildNamedStoreProcedureQueries(
|
||||||
|
Element element,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
if ( element == null ) {
|
if ( element == null ) {
|
||||||
return new ArrayList<NamedStoredProcedureQuery>();
|
return new ArrayList<NamedStoredProcedureQuery>();
|
||||||
}
|
}
|
||||||
|
@ -1969,12 +1978,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
String clazzName = parameterElement.attributeValue( "class" );
|
String clazzName = parameterElement.attributeValue( "class" );
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
XMLContext.buildSafeClassName( clazzName, defaults )
|
||||||
JPAOverriddenAnnotationReader.class
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||||
}
|
}
|
||||||
parameterDescriptor.setValue( "type", clazz );
|
parameterDescriptor.setValue( "type", clazz );
|
||||||
|
@ -1992,12 +2000,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
String clazzName = classElement.getTextTrim();
|
String clazzName = classElement.getTextTrim();
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
XMLContext.buildSafeClassName( clazzName, defaults )
|
||||||
JPAOverriddenAnnotationReader.class
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||||
}
|
}
|
||||||
returnClasses.add( clazz );
|
returnClasses.add( clazz );
|
||||||
|
@ -2019,7 +2026,10 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element, XMLContext.Default defaults) {
|
public static List<SqlResultSetMapping> buildSqlResultsetMappings(
|
||||||
|
Element element,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
final List<SqlResultSetMapping> builtResultSetMappings = new ArrayList<SqlResultSetMapping>();
|
final List<SqlResultSetMapping> builtResultSetMappings = new ArrayList<SqlResultSetMapping>();
|
||||||
if ( element == null ) {
|
if ( element == null ) {
|
||||||
return builtResultSetMappings;
|
return builtResultSetMappings;
|
||||||
|
@ -2049,19 +2059,19 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
entityResultAnnotations = new ArrayList<EntityResult>();
|
entityResultAnnotations = new ArrayList<EntityResult>();
|
||||||
}
|
}
|
||||||
// process the <entity-result/>
|
// process the <entity-result/>
|
||||||
entityResultAnnotations.add( buildEntityResult( resultElement, defaults ) );
|
entityResultAnnotations.add( buildEntityResult( resultElement, defaults, classLoaderAccess ) );
|
||||||
}
|
}
|
||||||
else if ( "column-result".equals( resultElement.getName() ) ) {
|
else if ( "column-result".equals( resultElement.getName() ) ) {
|
||||||
if ( columnResultAnnotations == null ) {
|
if ( columnResultAnnotations == null ) {
|
||||||
columnResultAnnotations = new ArrayList<ColumnResult>();
|
columnResultAnnotations = new ArrayList<ColumnResult>();
|
||||||
}
|
}
|
||||||
columnResultAnnotations.add( buildColumnResult( resultElement, defaults ) );
|
columnResultAnnotations.add( buildColumnResult( resultElement, defaults, classLoaderAccess ) );
|
||||||
}
|
}
|
||||||
else if ( "constructor-result".equals( resultElement.getName() ) ) {
|
else if ( "constructor-result".equals( resultElement.getName() ) ) {
|
||||||
if ( constructorResultAnnotations == null ) {
|
if ( constructorResultAnnotations == null ) {
|
||||||
constructorResultAnnotations = new ArrayList<ConstructorResult>();
|
constructorResultAnnotations = new ArrayList<ConstructorResult>();
|
||||||
}
|
}
|
||||||
constructorResultAnnotations.add( buildConstructorResult( resultElement, defaults ) );
|
constructorResultAnnotations.add( buildConstructorResult( resultElement, defaults, classLoaderAccess ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// most likely the <result-class/> this code used to handle. I have left the code here,
|
// most likely the <result-class/> this code used to handle. I have left the code here,
|
||||||
|
@ -2114,10 +2124,13 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
return builtResultSetMappings;
|
return builtResultSetMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EntityResult buildEntityResult(Element entityResultElement, XMLContext.Default defaults) {
|
private static EntityResult buildEntityResult(
|
||||||
|
Element entityResultElement,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
final AnnotationDescriptor entityResultDescriptor = new AnnotationDescriptor( EntityResult.class );
|
final AnnotationDescriptor entityResultDescriptor = new AnnotationDescriptor( EntityResult.class );
|
||||||
|
|
||||||
final Class entityClass = resolveClassReference( entityResultElement.attributeValue( "entity-class" ), defaults );
|
final Class entityClass = resolveClassReference( entityResultElement.attributeValue( "entity-class" ), defaults, classLoaderAccess );
|
||||||
entityResultDescriptor.setValue( "entityClass", entityClass );
|
entityResultDescriptor.setValue( "entityClass", entityClass );
|
||||||
|
|
||||||
copyStringAttribute( entityResultDescriptor, entityResultElement, "discriminator-column", false );
|
copyStringAttribute( entityResultDescriptor, entityResultElement, "discriminator-column", false );
|
||||||
|
@ -2136,22 +2149,27 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
return AnnotationFactory.create( entityResultDescriptor );
|
return AnnotationFactory.create( entityResultDescriptor );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Class resolveClassReference(String className, XMLContext.Default defaults) {
|
private static Class resolveClassReference(
|
||||||
|
String className,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
if ( className == null ) {
|
if ( className == null ) {
|
||||||
throw new AnnotationException( "<entity-result> without entity-class. " + SCHEMA_VALIDATION );
|
throw new AnnotationException( "<entity-result> without entity-class. " + SCHEMA_VALIDATION );
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return ReflectHelper.classForName(
|
return classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( className, defaults ),
|
XMLContext.buildSafeClassName( className, defaults )
|
||||||
JPAOverriddenAnnotationReader.class
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException( "Unable to find specified class: " + className, e );
|
throw new AnnotationException( "Unable to find specified class: " + className, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ColumnResult buildColumnResult(Element columnResultElement, XMLContext.Default defaults) {
|
private static ColumnResult buildColumnResult(
|
||||||
|
Element columnResultElement,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
// AnnotationDescriptor columnResultDescriptor = new AnnotationDescriptor( ColumnResult.class );
|
// AnnotationDescriptor columnResultDescriptor = new AnnotationDescriptor( ColumnResult.class );
|
||||||
// copyStringAttribute( columnResultDescriptor, columnResultElement, "name", true );
|
// copyStringAttribute( columnResultDescriptor, columnResultElement, "name", true );
|
||||||
// return AnnotationFactory.create( columnResultDescriptor );
|
// return AnnotationFactory.create( columnResultDescriptor );
|
||||||
|
@ -2160,20 +2178,23 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
copyStringAttribute( columnResultDescriptor, columnResultElement, "name", true );
|
copyStringAttribute( columnResultDescriptor, columnResultElement, "name", true );
|
||||||
final String columnTypeName = columnResultElement.attributeValue( "class" );
|
final String columnTypeName = columnResultElement.attributeValue( "class" );
|
||||||
if ( StringHelper.isNotEmpty( columnTypeName ) ) {
|
if ( StringHelper.isNotEmpty( columnTypeName ) ) {
|
||||||
columnResultDescriptor.setValue( "type", resolveClassReference( columnTypeName, defaults ) );
|
columnResultDescriptor.setValue( "type", resolveClassReference( columnTypeName, defaults, classLoaderAccess ) );
|
||||||
}
|
}
|
||||||
return AnnotationFactory.create( columnResultDescriptor );
|
return AnnotationFactory.create( columnResultDescriptor );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ConstructorResult buildConstructorResult(Element constructorResultElement, XMLContext.Default defaults) {
|
private static ConstructorResult buildConstructorResult(
|
||||||
|
Element constructorResultElement,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
AnnotationDescriptor constructorResultDescriptor = new AnnotationDescriptor( ConstructorResult.class );
|
AnnotationDescriptor constructorResultDescriptor = new AnnotationDescriptor( ConstructorResult.class );
|
||||||
|
|
||||||
final Class entityClass = resolveClassReference( constructorResultElement.attributeValue( "target-class" ), defaults );
|
final Class entityClass = resolveClassReference( constructorResultElement.attributeValue( "target-class" ), defaults, classLoaderAccess );
|
||||||
constructorResultDescriptor.setValue( "targetClass", entityClass );
|
constructorResultDescriptor.setValue( "targetClass", entityClass );
|
||||||
|
|
||||||
List<ColumnResult> columnResultAnnotations = new ArrayList<ColumnResult>();
|
List<ColumnResult> columnResultAnnotations = new ArrayList<ColumnResult>();
|
||||||
for ( Element columnResultElement : (List<Element>) constructorResultElement.elements( "column" ) ) {
|
for ( Element columnResultElement : (List<Element>) constructorResultElement.elements( "column" ) ) {
|
||||||
columnResultAnnotations.add( buildColumnResult( columnResultElement, defaults ) );
|
columnResultAnnotations.add( buildColumnResult( columnResultElement, defaults, classLoaderAccess ) );
|
||||||
}
|
}
|
||||||
constructorResultDescriptor.setValue(
|
constructorResultDescriptor.setValue(
|
||||||
"columns",
|
"columns",
|
||||||
|
@ -2201,7 +2222,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
|
|
||||||
private NamedQueries getNamedQueries(Element tree, XMLContext.Default defaults) {
|
private NamedQueries getNamedQueries(Element tree, XMLContext.Default defaults) {
|
||||||
//TODO avoid the Proxy Creation (@NamedQueries) when possible
|
//TODO avoid the Proxy Creation (@NamedQueries) when possible
|
||||||
List<NamedQuery> queries = (List<NamedQuery>) buildNamedQueries( tree, false, defaults );
|
List<NamedQuery> queries = (List<NamedQuery>) buildNamedQueries( tree, false, defaults, classLoaderAccess );
|
||||||
if ( defaults.canUseJavaAnnotations() ) {
|
if ( defaults.canUseJavaAnnotations() ) {
|
||||||
NamedQuery annotation = getPhysicalAnnotation( NamedQuery.class );
|
NamedQuery annotation = getPhysicalAnnotation( NamedQuery.class );
|
||||||
addNamedQueryIfNeeded( annotation, queries );
|
addNamedQueryIfNeeded( annotation, queries );
|
||||||
|
@ -2239,7 +2260,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedEntityGraphs getNamedEntityGraphs(Element tree, XMLContext.Default defaults) {
|
private NamedEntityGraphs getNamedEntityGraphs(Element tree, XMLContext.Default defaults) {
|
||||||
List<NamedEntityGraph> queries = buildNamedEntityGraph( tree, defaults );
|
List<NamedEntityGraph> queries = buildNamedEntityGraph( tree, defaults, classLoaderAccess );
|
||||||
if ( defaults.canUseJavaAnnotations() ) {
|
if ( defaults.canUseJavaAnnotations() ) {
|
||||||
NamedEntityGraph annotation = getPhysicalAnnotation( NamedEntityGraph.class );
|
NamedEntityGraph annotation = getPhysicalAnnotation( NamedEntityGraph.class );
|
||||||
addNamedEntityGraphIfNeeded( annotation, queries );
|
addNamedEntityGraphIfNeeded( annotation, queries );
|
||||||
|
@ -2278,7 +2299,7 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedStoredProcedureQueries getNamedStoredProcedureQueries(Element tree, XMLContext.Default defaults) {
|
private NamedStoredProcedureQueries getNamedStoredProcedureQueries(Element tree, XMLContext.Default defaults) {
|
||||||
List<NamedStoredProcedureQuery> queries = buildNamedStoreProcedureQueries( tree, defaults );
|
List<NamedStoredProcedureQuery> queries = buildNamedStoreProcedureQueries( tree, defaults, classLoaderAccess );
|
||||||
if ( defaults.canUseJavaAnnotations() ) {
|
if ( defaults.canUseJavaAnnotations() ) {
|
||||||
NamedStoredProcedureQuery annotation = getPhysicalAnnotation( NamedStoredProcedureQuery.class );
|
NamedStoredProcedureQuery annotation = getPhysicalAnnotation( NamedStoredProcedureQuery.class );
|
||||||
addNamedStoredProcedureQueryIfNeeded( annotation, queries );
|
addNamedStoredProcedureQueryIfNeeded( annotation, queries );
|
||||||
|
@ -2316,8 +2337,10 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private NamedNativeQueries getNamedNativeQueries(Element tree, XMLContext.Default defaults) {
|
private NamedNativeQueries getNamedNativeQueries(
|
||||||
List<NamedNativeQuery> queries = (List<NamedNativeQuery>) buildNamedQueries( tree, true, defaults );
|
Element tree,
|
||||||
|
XMLContext.Default defaults) {
|
||||||
|
List<NamedNativeQuery> queries = (List<NamedNativeQuery>) buildNamedQueries( tree, true, defaults, classLoaderAccess );
|
||||||
if ( defaults.canUseJavaAnnotations() ) {
|
if ( defaults.canUseJavaAnnotations() ) {
|
||||||
NamedNativeQuery annotation = getPhysicalAnnotation( NamedNativeQuery.class );
|
NamedNativeQuery annotation = getPhysicalAnnotation( NamedNativeQuery.class );
|
||||||
addNamedNativeQueryIfNeeded( annotation, queries );
|
addNamedNativeQueryIfNeeded( annotation, queries );
|
||||||
|
@ -2373,7 +2396,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
|
ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List buildNamedQueries(Element element, boolean isNative, XMLContext.Default defaults) {
|
public static List buildNamedQueries(
|
||||||
|
Element element,
|
||||||
|
boolean isNative,
|
||||||
|
XMLContext.Default defaults,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
if ( element == null ) {
|
if ( element == null ) {
|
||||||
return new ArrayList();
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
@ -2381,9 +2408,8 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
element.elements( "named-native-query" ) :
|
element.elements( "named-native-query" ) :
|
||||||
element.elements( "named-query" );
|
element.elements( "named-query" );
|
||||||
List namedQueries = new ArrayList();
|
List namedQueries = new ArrayList();
|
||||||
Iterator it = namedQueryElementList.listIterator();
|
for ( Object aNamedQueryElementList : namedQueryElementList ) {
|
||||||
while ( it.hasNext() ) {
|
Element subelement = (Element) aNamedQueryElementList;
|
||||||
Element subelement = (Element) it.next();
|
|
||||||
AnnotationDescriptor ann = new AnnotationDescriptor(
|
AnnotationDescriptor ann = new AnnotationDescriptor(
|
||||||
isNative ? NamedNativeQuery.class : NamedQuery.class
|
isNative ? NamedNativeQuery.class : NamedQuery.class
|
||||||
);
|
);
|
||||||
|
@ -2399,12 +2425,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
if ( StringHelper.isNotEmpty( clazzName ) ) {
|
if ( StringHelper.isNotEmpty( clazzName ) ) {
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( clazzName, defaults ),
|
XMLContext.buildSafeClassName( clazzName, defaults )
|
||||||
JPAOverriddenAnnotationReader.class
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch (ClassLoadingException e) {
|
||||||
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
throw new AnnotationException( "Unable to find entity-class: " + clazzName, e );
|
||||||
}
|
}
|
||||||
ann.setValue( "resultClass", clazz );
|
ann.setValue( "resultClass", clazz );
|
||||||
|
@ -2597,12 +2622,11 @@ public class JPAOverriddenAnnotationReader implements AnnotationReader {
|
||||||
AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class );
|
AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class );
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName(
|
clazz = classLoaderAccess.classForName(
|
||||||
XMLContext.buildSafeClassName( attr.getValue(), defaults ),
|
XMLContext.buildSafeClassName( attr.getValue(), defaults )
|
||||||
this.getClass()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AnnotationException( "Unable to find id-class: " + attr.getValue(), e );
|
throw new AnnotationException( "Unable to find id-class: " + attr.getValue(), e );
|
||||||
}
|
}
|
||||||
ad.setValue( "value", clazz );
|
ad.setValue( "value", clazz );
|
||||||
|
|
|
@ -15,10 +15,11 @@ import javax.persistence.AccessType;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
import org.hibernate.cfg.AttributeConverterDefinition;
|
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
@ -33,6 +34,8 @@ import org.dom4j.Element;
|
||||||
public class XMLContext implements Serializable {
|
public class XMLContext implements Serializable {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
|
||||||
|
|
||||||
|
private final ClassLoaderAccess classLoaderAccess;
|
||||||
|
|
||||||
private Default globalDefaults;
|
private Default globalDefaults;
|
||||||
private Map<String, Element> classOverriding = new HashMap<String, Element>();
|
private Map<String, Element> classOverriding = new HashMap<String, Element>();
|
||||||
private Map<String, Default> defaultsOverriding = new HashMap<String, Default>();
|
private Map<String, Default> defaultsOverriding = new HashMap<String, Default>();
|
||||||
|
@ -40,6 +43,10 @@ public class XMLContext implements Serializable {
|
||||||
private List<String> defaultEntityListeners = new ArrayList<String>();
|
private List<String> defaultEntityListeners = new ArrayList<String>();
|
||||||
private boolean hasContext = false;
|
private boolean hasContext = false;
|
||||||
|
|
||||||
|
public XMLContext(ClassLoaderAccess classLoaderAccess) {
|
||||||
|
this.classLoaderAccess = classLoaderAccess;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param doc The xml document to add
|
* @param doc The xml document to add
|
||||||
* @return Add a xml document to this context and return the list of added class names.
|
* @return Add a xml document to this context and return the list of added class names.
|
||||||
|
@ -182,14 +189,14 @@ public class XMLContext implements Serializable {
|
||||||
final boolean autoApply = autoApplyAttribute != null && Boolean.parseBoolean( autoApplyAttribute );
|
final boolean autoApply = autoApplyAttribute != null && Boolean.parseBoolean( autoApplyAttribute );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Class<? extends AttributeConverter> attributeConverterClass = ReflectHelper.classForName(
|
final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName(
|
||||||
className
|
className
|
||||||
);
|
);
|
||||||
attributeConverterDefinitions.add(
|
attributeConverterDefinitions.add(
|
||||||
new AttributeConverterDefinition( attributeConverterClass.newInstance(), autoApply )
|
new AttributeConverterDefinition( attributeConverterClass.newInstance(), autoApply )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassLoadingException e) {
|
||||||
throw new AnnotationException( "Unable to locate specified AttributeConverter implementation class : " + className, e );
|
throw new AnnotationException( "Unable to locate specified AttributeConverter implementation class : " + className, e );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
|
@ -18,6 +18,8 @@ import javax.validation.Validator;
|
||||||
import javax.validation.ValidatorFactory;
|
import javax.validation.ValidatorFactory;
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.boot.internal.ClassLoaderAccessImpl;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.event.spi.PreDeleteEvent;
|
import org.hibernate.event.spi.PreDeleteEvent;
|
||||||
import org.hibernate.event.spi.PreDeleteEventListener;
|
import org.hibernate.event.spi.PreDeleteEventListener;
|
||||||
|
@ -49,29 +51,29 @@ public class BeanValidationEventListener
|
||||||
private GroupsPerOperation groupsPerOperation;
|
private GroupsPerOperation groupsPerOperation;
|
||||||
boolean initialized;
|
boolean initialized;
|
||||||
|
|
||||||
/**
|
|
||||||
* No-arg constructor used when listener is configured via configuration file
|
|
||||||
*/
|
|
||||||
public BeanValidationEventListener() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used in an environment where validator factory is injected (JPA2).
|
* Constructor used in an environment where validator factory is injected (JPA2).
|
||||||
*
|
*
|
||||||
* @param factory The {@code ValidatorFactory} to use to create {@code Validator} instance(s)
|
* @param factory The {@code ValidatorFactory} to use to create {@code Validator} instance(s)
|
||||||
* @param settings Configued properties
|
* @param settings Configued properties
|
||||||
*/
|
*/
|
||||||
public BeanValidationEventListener(ValidatorFactory factory, Map settings) {
|
public BeanValidationEventListener(ValidatorFactory factory, Map settings, ClassLoaderService classLoaderService) {
|
||||||
init( factory, settings );
|
init( factory, settings, classLoaderService );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(Map settings) {
|
public void initialize(Map settings, ClassLoaderService classLoaderService) {
|
||||||
if ( !initialized ) {
|
if ( !initialized ) {
|
||||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||||
init( factory, settings );
|
init( factory, settings, classLoaderService );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void init(ValidatorFactory factory, Map settings, ClassLoaderService classLoaderService) {
|
||||||
|
this.factory = factory;
|
||||||
|
groupsPerOperation = GroupsPerOperation.from( settings, new ClassLoaderAccessImpl( classLoaderService ) );
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean onPreInsert(PreInsertEvent event) {
|
public boolean onPreInsert(PreInsertEvent event) {
|
||||||
validate(
|
validate(
|
||||||
event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(),
|
event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(),
|
||||||
|
@ -96,12 +98,6 @@ public class BeanValidationEventListener
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(ValidatorFactory factory, Map settings) {
|
|
||||||
this.factory = factory;
|
|
||||||
groupsPerOperation = new GroupsPerOperation( settings );
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> void validate(T object, EntityMode mode, EntityPersister persister,
|
private <T> void validate(T object, EntityMode mode, EntityPersister persister,
|
||||||
SessionFactoryImplementor sessionFactory, GroupsPerOperation.Operation operation) {
|
SessionFactoryImplementor sessionFactory, GroupsPerOperation.Operation operation) {
|
||||||
if ( object == null || mode != EntityMode.POJO ) {
|
if ( object == null || mode != EntityMode.POJO ) {
|
||||||
|
|
|
@ -13,66 +13,81 @@ import java.util.Map;
|
||||||
import javax.validation.groups.Default;
|
import javax.validation.groups.Default;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
public class GroupsPerOperation {
|
public class GroupsPerOperation {
|
||||||
|
|
||||||
private static final String JPA_GROUP_PREFIX = "javax.persistence.validation.group.";
|
private static final String JPA_GROUP_PREFIX = "javax.persistence.validation.group.";
|
||||||
private static final String HIBERNATE_GROUP_PREFIX = "org.hibernate.validator.group.";
|
private static final String HIBERNATE_GROUP_PREFIX = "org.hibernate.validator.group.";
|
||||||
|
|
||||||
private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] { Default.class };
|
private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] { Default.class };
|
||||||
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
|
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
|
||||||
|
|
||||||
private Map<Operation, Class<?>[]> groupsPerOperation = new HashMap<Operation, Class<?>[]>(4);
|
private Map<Operation, Class<?>[]> groupsPerOperation = new HashMap<Operation, Class<?>[]>(4);
|
||||||
|
|
||||||
public GroupsPerOperation(Map settings) {
|
private GroupsPerOperation() {
|
||||||
setGroupsForOperation( Operation.INSERT, settings );
|
|
||||||
setGroupsForOperation( Operation.UPDATE, settings );
|
|
||||||
setGroupsForOperation( Operation.DELETE, settings );
|
|
||||||
setGroupsForOperation( Operation.DDL, settings );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setGroupsForOperation(Operation operation, Map settings) {
|
public static GroupsPerOperation from(Map settings, ClassLoaderAccess classLoaderAccess) {
|
||||||
Object property = settings.get( operation.getGroupPropertyName() );
|
GroupsPerOperation groupsPerOperation = new GroupsPerOperation();
|
||||||
|
|
||||||
|
applyOperationGrouping( groupsPerOperation, Operation.INSERT, settings, classLoaderAccess );
|
||||||
|
applyOperationGrouping( groupsPerOperation, Operation.UPDATE, settings, classLoaderAccess );
|
||||||
|
applyOperationGrouping( groupsPerOperation, Operation.DELETE, settings, classLoaderAccess );
|
||||||
|
applyOperationGrouping( groupsPerOperation, Operation.DDL, settings, classLoaderAccess );
|
||||||
|
|
||||||
|
return groupsPerOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyOperationGrouping(
|
||||||
|
GroupsPerOperation groupsPerOperation,
|
||||||
|
Operation operation,
|
||||||
|
Map settings,
|
||||||
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
|
groupsPerOperation.groupsPerOperation.put(
|
||||||
|
operation,
|
||||||
|
buildGroupsForOperation( operation, settings, classLoaderAccess )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?>[] buildGroupsForOperation(Operation operation, Map settings, ClassLoaderAccess classLoaderAccess) {
|
||||||
|
final Object property = settings.get( operation.getGroupPropertyName() );
|
||||||
|
|
||||||
Class<?>[] groups;
|
|
||||||
if ( property == null ) {
|
if ( property == null ) {
|
||||||
groups = operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
|
return operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if ( property instanceof String ) {
|
if ( property instanceof Class<?>[] ) {
|
||||||
String stringProperty = (String) property;
|
return (Class<?>[]) property;
|
||||||
String[] groupNames = stringProperty.split( "," );
|
}
|
||||||
if ( groupNames.length == 1 && groupNames[0].equals( "" ) ) {
|
|
||||||
groups = EMPTY_GROUPS;
|
if ( property instanceof String ) {
|
||||||
}
|
String stringProperty = (String) property;
|
||||||
else {
|
String[] groupNames = stringProperty.split( "," );
|
||||||
List<Class<?>> groupsList = new ArrayList<Class<?>>(groupNames.length);
|
if ( groupNames.length == 1 && groupNames[0].equals( "" ) ) {
|
||||||
for (String groupName : groupNames) {
|
return EMPTY_GROUPS;
|
||||||
String cleanedGroupName = groupName.trim();
|
}
|
||||||
if ( cleanedGroupName.length() > 0) {
|
|
||||||
try {
|
List<Class<?>> groupsList = new ArrayList<Class<?>>(groupNames.length);
|
||||||
groupsList.add( ReflectHelper.classForName( cleanedGroupName ) );
|
for (String groupName : groupNames) {
|
||||||
}
|
String cleanedGroupName = groupName.trim();
|
||||||
catch ( ClassNotFoundException e ) {
|
if ( cleanedGroupName.length() > 0) {
|
||||||
throw new HibernateException( "Unable to load class " + cleanedGroupName, e );
|
try {
|
||||||
}
|
groupsList.add( classLoaderAccess.classForName( cleanedGroupName ) );
|
||||||
}
|
}
|
||||||
|
catch ( ClassLoadingException e ) {
|
||||||
|
throw new HibernateException( "Unable to load class " + cleanedGroupName, e );
|
||||||
}
|
}
|
||||||
groups = groupsList.toArray( new Class<?>[groupsList.size()] );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( property instanceof Class<?>[] ) {
|
return groupsList.toArray( new Class<?>[groupsList.size()] );
|
||||||
groups = (Class<?>[]) property;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//null is bad and excluded by instanceof => exception is raised
|
|
||||||
throw new HibernateException( JPA_GROUP_PREFIX + operation.getGroupPropertyName() + " is of unknown type: String or Class<?>[] only");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
groupsPerOperation.put( operation, groups );
|
|
||||||
|
//null is bad and excluded by instanceof => exception is raised
|
||||||
|
throw new HibernateException( JPA_GROUP_PREFIX + operation.getGroupPropertyName() + " is of unknown type: String or Class<?>[] only");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?>[] get(Operation operation) {
|
public Class<?>[] get(Operation operation) {
|
||||||
|
|
|
@ -27,6 +27,10 @@ import javax.validation.metadata.PropertyDescriptor;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.internal.ClassLoaderAccessImpl;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
@ -35,7 +39,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||||
import org.hibernate.event.spi.EventType;
|
import org.hibernate.event.spi.EventType;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
|
@ -104,6 +107,7 @@ class TypeSafeActivator {
|
||||||
}
|
}
|
||||||
|
|
||||||
final ConfigurationService cfgService = activationContext.getServiceRegistry().getService( ConfigurationService.class );
|
final ConfigurationService cfgService = activationContext.getServiceRegistry().getService( ConfigurationService.class );
|
||||||
|
final ClassLoaderService classLoaderService = activationContext.getServiceRegistry().getService( ClassLoaderService.class );
|
||||||
|
|
||||||
// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
|
// de-activate not-null tracking at the core level when Bean Validation is present unless the user explicitly
|
||||||
// asks for it
|
// asks for it
|
||||||
|
@ -113,7 +117,8 @@ class TypeSafeActivator {
|
||||||
|
|
||||||
final BeanValidationEventListener listener = new BeanValidationEventListener(
|
final BeanValidationEventListener listener = new BeanValidationEventListener(
|
||||||
validatorFactory,
|
validatorFactory,
|
||||||
cfgService.getSettings()
|
cfgService.getSettings(),
|
||||||
|
classLoaderService
|
||||||
);
|
);
|
||||||
|
|
||||||
final EventListenerRegistry listenerRegistry = activationContext.getServiceRegistry()
|
final EventListenerRegistry listenerRegistry = activationContext.getServiceRegistry()
|
||||||
|
@ -125,7 +130,7 @@ class TypeSafeActivator {
|
||||||
listenerRegistry.appendListeners( EventType.PRE_UPDATE, listener );
|
listenerRegistry.appendListeners( EventType.PRE_UPDATE, listener );
|
||||||
listenerRegistry.appendListeners( EventType.PRE_DELETE, listener );
|
listenerRegistry.appendListeners( EventType.PRE_DELETE, listener );
|
||||||
|
|
||||||
listener.initialize( cfgService.getSettings() );
|
listener.initialize( cfgService.getSettings(), classLoaderService );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "UnusedParameters"})
|
@SuppressWarnings({"unchecked", "UnusedParameters"})
|
||||||
|
@ -145,7 +150,8 @@ class TypeSafeActivator {
|
||||||
factory,
|
factory,
|
||||||
activationContext.getMetadata().getEntityBindings(),
|
activationContext.getMetadata().getEntityBindings(),
|
||||||
cfgService.getSettings(),
|
cfgService.getSettings(),
|
||||||
activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect()
|
activationContext.getServiceRegistry().getService( JdbcServices.class ).getDialect(),
|
||||||
|
new ClassLoaderAccessImpl( null, activationContext.getServiceRegistry().getService( ClassLoaderService.class ) )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +160,13 @@ class TypeSafeActivator {
|
||||||
ValidatorFactory factory,
|
ValidatorFactory factory,
|
||||||
Collection<PersistentClass> persistentClasses,
|
Collection<PersistentClass> persistentClasses,
|
||||||
Map settings,
|
Map settings,
|
||||||
Dialect dialect) {
|
Dialect dialect,
|
||||||
Class<?>[] groupsArray = new GroupsPerOperation( settings ).get( GroupsPerOperation.Operation.DDL );
|
ClassLoaderAccess classLoaderAccess) {
|
||||||
|
Class<?>[] groupsArray = GroupsPerOperation.buildGroupsForOperation(
|
||||||
|
GroupsPerOperation.Operation.DDL,
|
||||||
|
settings,
|
||||||
|
classLoaderAccess
|
||||||
|
);
|
||||||
Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) );
|
Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) );
|
||||||
|
|
||||||
for ( PersistentClass persistentClass : persistentClasses ) {
|
for ( PersistentClass persistentClass : persistentClasses ) {
|
||||||
|
@ -166,9 +177,9 @@ class TypeSafeActivator {
|
||||||
}
|
}
|
||||||
Class<?> clazz;
|
Class<?> clazz;
|
||||||
try {
|
try {
|
||||||
clazz = ReflectHelper.classForName( className, TypeSafeActivator.class );
|
clazz = classLoaderAccess.classForName( className );
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new AssertionFailure( "Entity class not found", e );
|
throw new AssertionFailure( "Entity class not found", e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.hibernate.event.spi.PreLoadEventListener;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.property.BackrefPropertyAccessor;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.TypeHelper;
|
import org.hibernate.type.TypeHelper;
|
||||||
|
@ -149,7 +149,7 @@ public final class TwoPhaseLoad {
|
||||||
final Type[] types = persister.getPropertyTypes();
|
final Type[] types = persister.getPropertyTypes();
|
||||||
for ( int i = 0; i < hydratedState.length; i++ ) {
|
for ( int i = 0; i < hydratedState.length; i++ ) {
|
||||||
final Object value = hydratedState[i];
|
final Object value = hydratedState[i];
|
||||||
if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
|
if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!= PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||||
hydratedState[i] = types[i].resolve( value, session, entity );
|
hydratedState[i] = types[i].resolve( value, session, entity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.InstantiationException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.spi.IdentifierValue;
|
import org.hibernate.engine.spi.IdentifierValue;
|
||||||
import org.hibernate.engine.spi.VersionValue;
|
import org.hibernate.engine.spi.VersionValue;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.type.IdentifierType;
|
import org.hibernate.type.IdentifierType;
|
||||||
import org.hibernate.type.PrimitiveType;
|
import org.hibernate.type.PrimitiveType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
|
@ -9,15 +9,15 @@ package org.hibernate.engine.jdbc;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ClassLoaderHelper;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that
|
* A proxy for a ResultSet delegate, responsible for locally caching the columnName-to-columnIndex resolution that
|
||||||
|
@ -27,11 +27,8 @@ import org.jboss.logging.Logger;
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class ResultSetWrapperProxy implements InvocationHandler {
|
public class ResultSetWrapperProxy implements InvocationHandler {
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
private static final CoreMessageLogger LOG = messageLogger( ResultSetWrapperProxy.class );
|
||||||
CoreMessageLogger.class,
|
|
||||||
ResultSetWrapperProxy.class.getName()
|
|
||||||
);
|
|
||||||
private static final Class[] PROXY_INTERFACES = new Class[] { ResultSet.class };
|
|
||||||
private static final SqlExceptionHelper SQL_EXCEPTION_HELPER = new SqlExceptionHelper();
|
private static final SqlExceptionHelper SQL_EXCEPTION_HELPER = new SqlExceptionHelper();
|
||||||
|
|
||||||
private final ResultSet rs;
|
private final ResultSet rs;
|
||||||
|
@ -47,30 +44,20 @@ public class ResultSetWrapperProxy implements InvocationHandler {
|
||||||
*
|
*
|
||||||
* @param resultSet The resultSet to wrap.
|
* @param resultSet The resultSet to wrap.
|
||||||
* @param columnNameCache The cache storing data for converting column names to column indexes.
|
* @param columnNameCache The cache storing data for converting column names to column indexes.
|
||||||
|
* @param serviceRegistry Access to any needed services
|
||||||
|
*
|
||||||
* @return The generated proxy.
|
* @return The generated proxy.
|
||||||
*/
|
*/
|
||||||
public static ResultSet generateProxy(ResultSet resultSet, ColumnNameCache columnNameCache) {
|
public static ResultSet generateProxy(
|
||||||
return (ResultSet) Proxy.newProxyInstance(
|
ResultSet resultSet,
|
||||||
getProxyClassLoader(),
|
ColumnNameCache columnNameCache,
|
||||||
PROXY_INTERFACES,
|
ServiceRegistry serviceRegistry) {
|
||||||
new ResultSetWrapperProxy( resultSet, columnNameCache )
|
return serviceRegistry.getService( ClassLoaderService.class ).generateProxy(
|
||||||
|
new ResultSetWrapperProxy( resultSet, columnNameCache ),
|
||||||
|
ResultSet.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the appropriate class loader to which the generated proxy
|
|
||||||
* should be scoped.
|
|
||||||
*
|
|
||||||
* @return The class loader appropriate for proxy construction.
|
|
||||||
*/
|
|
||||||
public static ClassLoader getProxyClassLoader() {
|
|
||||||
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
|
|
||||||
if ( cl == null ) {
|
|
||||||
cl = ResultSet.class.getClassLoader();
|
|
||||||
}
|
|
||||||
return cl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ( "findColumn".equals( method.getName() ) ) {
|
if ( "findColumn".equals( method.getName() ) ) {
|
||||||
|
|
|
@ -193,12 +193,7 @@ public class DriverManagerConnectionProviderImpl
|
||||||
return (Driver) Class.forName( driverClassName ).newInstance();
|
return (Driver) Class.forName( driverClassName ).newInstance();
|
||||||
}
|
}
|
||||||
catch ( Exception e1 ) {
|
catch ( Exception e1 ) {
|
||||||
try{
|
throw new ServiceException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e1 );
|
||||||
return (Driver) ReflectHelper.classForName( driverClassName ).newInstance();
|
|
||||||
}
|
|
||||||
catch ( Exception e2 ) {
|
|
||||||
throw new ServiceException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e2 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
||||||
|
|
||||||
private SqlStatementLogger sqlStatementLogger;
|
private SqlStatementLogger sqlStatementLogger;
|
||||||
|
|
||||||
|
private ResultSetWrapperImpl resultSetWrapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
@ -55,6 +57,8 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
||||||
final boolean formatSQL = ConfigurationHelper.getBoolean( Environment.FORMAT_SQL, configValues, false );
|
final boolean formatSQL = ConfigurationHelper.getBoolean( Environment.FORMAT_SQL, configValues, false );
|
||||||
|
|
||||||
this.sqlStatementLogger = new SqlStatementLogger( showSQL, formatSQL );
|
this.sqlStatementLogger = new SqlStatementLogger( showSQL, formatSQL );
|
||||||
|
|
||||||
|
resultSetWrapper = new ResultSetWrapperImpl( serviceRegistry );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,6 +110,6 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetWrapper getResultSetWrapper() {
|
public ResultSetWrapper getResultSetWrapper() {
|
||||||
return ResultSetWrapperImpl.INSTANCE;
|
return resultSetWrapper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,11 @@ package org.hibernate.engine.jdbc.internal;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.engine.jdbc.ColumnNameCache;
|
import org.hibernate.engine.jdbc.ColumnNameCache;
|
||||||
import org.hibernate.engine.jdbc.ResultSetWrapperProxy;
|
import org.hibernate.engine.jdbc.ResultSetWrapperProxy;
|
||||||
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
|
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Hibernate implementation for wrapping a {@link ResultSet} in a
|
* Standard Hibernate implementation for wrapping a {@link ResultSet} in a
|
||||||
|
@ -20,16 +22,14 @@ import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class ResultSetWrapperImpl implements ResultSetWrapper {
|
public class ResultSetWrapperImpl implements ResultSetWrapper {
|
||||||
/**
|
private final ServiceRegistry serviceRegistry;
|
||||||
* Singleton access
|
|
||||||
*/
|
|
||||||
public static final ResultSetWrapper INSTANCE = new ResultSetWrapperImpl();
|
|
||||||
|
|
||||||
private ResultSetWrapperImpl() {
|
public ResultSetWrapperImpl(ServiceRegistry serviceRegistry) {
|
||||||
|
this.serviceRegistry = serviceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache) {
|
public ResultSet wrap(ResultSet resultSet, ColumnNameCache columnNameCache) {
|
||||||
return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache );
|
return ResultSetWrapperProxy.generateProxy( resultSet, columnNameCache, serviceRegistry );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.ScrollableResults;
|
import org.hibernate.ScrollableResults;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
|
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
|
||||||
import org.hibernate.engine.spi.QueryParameters;
|
import org.hibernate.engine.spi.QueryParameters;
|
||||||
import org.hibernate.engine.spi.RowSelection;
|
import org.hibernate.engine.spi.RowSelection;
|
||||||
|
@ -279,7 +280,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
||||||
|
|
||||||
final AST hqlAst = parser.getAST();
|
final AST hqlAst = parser.getAST();
|
||||||
|
|
||||||
final NodeTraverser walker = new NodeTraverser( new JavaConstantConverter() );
|
final NodeTraverser walker = new NodeTraverser( new JavaConstantConverter( factory ) );
|
||||||
walker.traverseDepthFirst( hqlAst );
|
walker.traverseDepthFirst( hqlAst );
|
||||||
|
|
||||||
showHqlAst( hqlAst );
|
showHqlAst( hqlAst );
|
||||||
|
@ -585,7 +586,14 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
|
public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
|
||||||
|
private final SessionFactoryImplementor factory;
|
||||||
private AST dotRoot;
|
private AST dotRoot;
|
||||||
|
|
||||||
|
public JavaConstantConverter(SessionFactoryImplementor factory) {
|
||||||
|
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AST node) {
|
public void visit(AST node) {
|
||||||
if ( dotRoot != null ) {
|
if ( dotRoot != null ) {
|
||||||
|
@ -604,7 +612,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
||||||
}
|
}
|
||||||
private void handleDotStructure(AST dotStructureRoot) {
|
private void handleDotStructure(AST dotStructureRoot) {
|
||||||
final String expression = ASTUtil.getPathText( dotStructureRoot );
|
final String expression = ASTUtil.getPathText( dotStructureRoot );
|
||||||
final Object constant = ReflectHelper.getConstantValue( expression );
|
final Object constant = ReflectHelper.getConstantValue( expression, factory.getServiceRegistry().getService( ClassLoaderService.class ) );
|
||||||
if ( constant != null ) {
|
if ( constant != null ) {
|
||||||
dotStructureRoot.setFirstChild( null );
|
dotStructureRoot.setFirstChild( null );
|
||||||
dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT );
|
dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT );
|
||||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
import org.hibernate.PropertyNotFoundException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.hql.internal.ast.DetailedSemanticException;
|
import org.hibernate.hql.internal.ast.DetailedSemanticException;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
@ -165,10 +167,13 @@ public class ConstructorNode extends SelectExpressionList implements AggregatedS
|
||||||
throw new SemanticException( "Unable to locate class [" + path + "]" );
|
throw new SemanticException( "Unable to locate class [" + path + "]" );
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class holderClass = ReflectHelper.classForName( className );
|
final Class holderClass = getSessionFactoryHelper().getFactory()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class )
|
||||||
|
.classForName( className );
|
||||||
return ReflectHelper.getConstructor( holderClass, constructorArgumentTypes );
|
return ReflectHelper.getConstructor( holderClass, constructorArgumentTypes );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException e) {
|
catch (ClassLoadingException e) {
|
||||||
throw new DetailedSemanticException( "Unable to locate class [" + className + "]", e );
|
throw new DetailedSemanticException( "Unable to locate class [" + className + "]", e );
|
||||||
}
|
}
|
||||||
catch (PropertyNotFoundException e) {
|
catch (PropertyNotFoundException e) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.hql.internal.ast.tree;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.hql.spi.QueryTranslator;
|
import org.hibernate.hql.spi.QueryTranslator;
|
||||||
|
@ -38,7 +39,7 @@ public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, Ses
|
||||||
// this method to get called twice. The first time with an empty string
|
// this method to get called twice. The first time with an empty string
|
||||||
if ( StringHelper.isNotEmpty( s ) ) {
|
if ( StringHelper.isNotEmpty( s ) ) {
|
||||||
constantExpression = s;
|
constantExpression = s;
|
||||||
constantValue = ReflectHelper.getConstantValue( s );
|
constantValue = ReflectHelper.getConstantValue( s, factory.getServiceRegistry().getService( ClassLoaderService.class ) );
|
||||||
heuristicType = factory.getTypeResolver().heuristicType( constantValue.getClass().getName() );
|
heuristicType = factory.getTypeResolver().heuristicType( constantValue.getClass().getName() );
|
||||||
super.setText( s );
|
super.setText( s );
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.text.DecimalFormat;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
|
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
|
||||||
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
import org.hibernate.hql.internal.antlr.SqlTokenTypes;
|
||||||
|
@ -107,7 +108,7 @@ public class LiteralProcessor implements HqlSqlTokenTypes {
|
||||||
setSQLValue( node, text, discrim );
|
setSQLValue( node, text, discrim );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Object value = ReflectHelper.getConstantValue( text );
|
Object value = ReflectHelper.getConstantValue( text, walker.getSessionFactoryHelper().getFactory().getServiceRegistry().getService( ClassLoaderService.class ) );
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
throw new InvalidPathException( "Invalid path: '" + text + "'" );
|
throw new InvalidPathException( "Invalid path: '" + text + "'" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@ import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.dialect.function.SQLFunction;
|
import org.hibernate.dialect.function.SQLFunction;
|
||||||
import org.hibernate.hql.internal.QuerySplitter;
|
import org.hibernate.hql.internal.QuerySplitter;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -75,10 +76,12 @@ public class SelectParser implements Parser {
|
||||||
if ( afterNew ) {
|
if ( afterNew ) {
|
||||||
afterNew = false;
|
afterNew = false;
|
||||||
try {
|
try {
|
||||||
holderClass = ReflectHelper.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) );
|
holderClass = q.getFactory().getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class )
|
||||||
|
.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) );
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException cnfe ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new QueryException( cnfe );
|
throw new QueryException( e );
|
||||||
}
|
}
|
||||||
if ( holderClass == null ) {
|
if ( holderClass == null ) {
|
||||||
throw new QueryException( "class not found: " + token );
|
throw new QueryException( "class not found: " + token );
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.engine.internal.JoinSequence;
|
import org.hibernate.engine.internal.JoinSequence;
|
||||||
import org.hibernate.hql.spi.QueryTranslator;
|
import org.hibernate.hql.spi.QueryTranslator;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
@ -418,7 +419,7 @@ public class WhereParser implements Parser {
|
||||||
Object constant;
|
Object constant;
|
||||||
if (
|
if (
|
||||||
token.indexOf( '.' ) > -1 &&
|
token.indexOf( '.' ) > -1 &&
|
||||||
( constant = ReflectHelper.getConstantValue( token ) ) != null
|
( constant = ReflectHelper.getConstantValue( token, q.getFactory().getServiceRegistry().getService( ClassLoaderService.class ) ) ) != null
|
||||||
) {
|
) {
|
||||||
Type type;
|
Type type;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -11,8 +11,8 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,6 @@ import org.hibernate.type.Type;
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Assigned implements IdentifierGenerator, Configurable {
|
public class Assigned implements IdentifierGenerator, Configurable {
|
||||||
|
|
||||||
private String entityName;
|
private String entityName;
|
||||||
|
@ -41,7 +40,7 @@ public class Assigned implements IdentifierGenerator, Configurable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
entityName = params.getProperty( ENTITY_NAME );
|
entityName = params.getProperty( ENTITY_NAME );
|
||||||
if ( entityName == null ) {
|
if ( entityName == null ) {
|
||||||
throw new MappingException("no entity name");
|
throw new MappingException("no entity name");
|
||||||
|
|
|
@ -9,14 +9,16 @@ package org.hibernate.id;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An <tt>IdentifierGenerator</tt> that supports "configuration".
|
* An {@link IdentifierGenerator} that supports "configuration".
|
||||||
*
|
*
|
||||||
* @see IdentifierGenerator
|
* @see IdentifierGenerator
|
||||||
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface Configurable {
|
public interface Configurable {
|
||||||
/**
|
/**
|
||||||
|
@ -24,8 +26,9 @@ public interface Configurable {
|
||||||
* specified by the user as <tt><param></tt> elements.
|
* specified by the user as <tt><param></tt> elements.
|
||||||
* This method is called just once, following instantiation.
|
* This method is called just once, following instantiation.
|
||||||
*
|
*
|
||||||
|
* @param type The id property type descriptor
|
||||||
* @param params param values, keyed by parameter name
|
* @param params param values, keyed by parameter name
|
||||||
|
* @param serviceRegistry Access to service that may be needed.
|
||||||
*/
|
*/
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnvironment) throws MappingException;
|
void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.mapping.Selectable;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
import org.hibernate.mapping.ValueVisitor;
|
import org.hibernate.mapping.ValueVisitor;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ public class ExportableColumn extends Column {
|
||||||
BasicType type,
|
BasicType type,
|
||||||
String dbTypeDeclaration) {
|
String dbTypeDeclaration) {
|
||||||
super( name );
|
super( name );
|
||||||
setValue( new ValueImpl( this, table, type ) );
|
setValue( new ValueImpl( this, table, type, database ) );
|
||||||
setSqlType( dbTypeDeclaration );
|
setSqlType( dbTypeDeclaration );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +52,13 @@ public class ExportableColumn extends Column {
|
||||||
private final ExportableColumn column;
|
private final ExportableColumn column;
|
||||||
private final Table table;
|
private final Table table;
|
||||||
private final BasicType type;
|
private final BasicType type;
|
||||||
|
private final Database database;
|
||||||
|
|
||||||
public ValueImpl(ExportableColumn column, Table table, BasicType type) {
|
public ValueImpl(ExportableColumn column, Table table, BasicType type, Database database) {
|
||||||
this.column = column;
|
this.column = column;
|
||||||
this.table = table;
|
this.table = table;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,6 +133,11 @@ public class ExportableColumn extends Column {
|
||||||
public Object accept(ValueVisitor visitor) {
|
public Object accept(ValueVisitor visitor) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceRegistry getServiceRegistry() {
|
||||||
|
return database.getBuildingOptions().getServiceRegistry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ColumnIterator implements Iterator<Selectable> {
|
public static class ColumnIterator implements Iterator<Selectable> {
|
||||||
|
|
|
@ -13,10 +13,10 @@ import org.hibernate.MappingException;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.TransientObjectException;
|
import org.hibernate.TransientObjectException;
|
||||||
import org.hibernate.engine.internal.ForeignKeys;
|
import org.hibernate.engine.internal.ForeignKeys;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.loader.PropertyPath;
|
import org.hibernate.loader.PropertyPath;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public class ForeignGenerator implements IdentifierGenerator, Configurable {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
propertyName = params.getProperty( "property" );
|
propertyName = params.getProperty( "property" );
|
||||||
entityName = params.getProperty( ENTITY_NAME );
|
entityName = params.getProperty( ENTITY_NAME );
|
||||||
if ( propertyName==null ) {
|
if ( propertyName==null ) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,17 +55,18 @@ public class IncrementGenerator implements IdentifierGenerator, Configurable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
returnClass = type.getReturnedClass();
|
returnClass = type.getReturnedClass();
|
||||||
|
|
||||||
ObjectNameNormalizer normalizer =
|
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||||
|
final ObjectNameNormalizer normalizer =
|
||||||
(ObjectNameNormalizer) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );
|
(ObjectNameNormalizer) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );
|
||||||
|
|
||||||
String column = params.getProperty( "column" );
|
String column = params.getProperty( "column" );
|
||||||
if ( column == null ) {
|
if ( column == null ) {
|
||||||
column = params.getProperty( PersistentIdentifierGenerator.PK );
|
column = params.getProperty( PersistentIdentifierGenerator.PK );
|
||||||
}
|
}
|
||||||
column = normalizer.normalizeIdentifierQuoting( column ).render( jdbcEnv.getDialect() );
|
column = normalizer.normalizeIdentifierQuoting( column ).render( jdbcEnvironment.getDialect() );
|
||||||
|
|
||||||
String tableList = params.getProperty( "tables" );
|
String tableList = params.getProperty( "tables" );
|
||||||
if ( tableList == null ) {
|
if ( tableList == null ) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.PrimaryKey;
|
import org.hibernate.mapping.PrimaryKey;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.LongType;
|
import org.hibernate.type.LongType;
|
||||||
import org.hibernate.type.StringType;
|
import org.hibernate.type.StringType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -246,8 +247,9 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"StatementWithEmptyBody", "deprecation"})
|
@SuppressWarnings({"StatementWithEmptyBody", "deprecation"})
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER );
|
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||||
|
final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER );
|
||||||
|
|
||||||
qualifiedTableName = QualifiedNameParser.INSTANCE.parse(
|
qualifiedTableName = QualifiedNameParser.INSTANCE.parse(
|
||||||
ConfigurationHelper.getString( ID_TABLE, params, DEFAULT_TABLE ),
|
ConfigurationHelper.getString( ID_TABLE, params, DEFAULT_TABLE ),
|
||||||
|
@ -255,9 +257,9 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
||||||
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
|
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
tableName = jdbcEnv.getQualifiedObjectNameFormatter().format(
|
tableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
|
||||||
qualifiedTableName,
|
qualifiedTableName,
|
||||||
jdbcEnv.getDialect()
|
jdbcEnvironment.getDialect()
|
||||||
);
|
);
|
||||||
pkColumnName = normalizer.toDatabaseIdentifierText(
|
pkColumnName = normalizer.toDatabaseIdentifierText(
|
||||||
ConfigurationHelper.getString( PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN )
|
ConfigurationHelper.getString( PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN )
|
||||||
|
@ -272,9 +274,9 @@ public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenera
|
||||||
query = "select " +
|
query = "select " +
|
||||||
valueColumnName +
|
valueColumnName +
|
||||||
" from " +
|
" from " +
|
||||||
jdbcEnv.getDialect().appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) +
|
jdbcEnvironment.getDialect().appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) +
|
||||||
" where " + pkColumnName + " = '" + keyValue + "'" +
|
" where " + pkColumnName + " = '" + keyValue + "'" +
|
||||||
jdbcEnv.getDialect().getForUpdateString();
|
jdbcEnvironment.getDialect().getForUpdateString();
|
||||||
|
|
||||||
update = "update " +
|
update = "update " +
|
||||||
tableName +
|
tableName +
|
||||||
|
|
|
@ -15,11 +15,11 @@ import java.util.Properties;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.insert.AbstractSelectingDelegate;
|
import org.hibernate.id.insert.AbstractSelectingDelegate;
|
||||||
import org.hibernate.id.insert.IdentifierGeneratingInsert;
|
import org.hibernate.id.insert.IdentifierGeneratingInsert;
|
||||||
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
|
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +35,7 @@ public class SelectGenerator extends AbstractPostInsertGenerator implements Conf
|
||||||
private String uniqueKeyPropertyName;
|
private String uniqueKeyPropertyName;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnvironment) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
uniqueKeyPropertyName = params.getProperty( "key" );
|
uniqueKeyPropertyName = params.getProperty( "key" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -79,18 +80,19 @@ public class SequenceGenerator
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("StatementWithEmptyBody")
|
@SuppressWarnings("StatementWithEmptyBody")
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
identifierType = type;
|
identifierType = type;
|
||||||
parameters = params.getProperty( PARAMETERS );
|
parameters = params.getProperty( PARAMETERS );
|
||||||
|
|
||||||
final Dialect dialect = jdbcEnv.getDialect();
|
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||||
|
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||||
final ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
|
final ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER );
|
||||||
qualifiedSequenceName = QualifiedNameParser.INSTANCE.parse(
|
qualifiedSequenceName = QualifiedNameParser.INSTANCE.parse(
|
||||||
ConfigurationHelper.getString( SEQUENCE, params, "hibernate_sequence" ),
|
ConfigurationHelper.getString( SEQUENCE, params, "hibernate_sequence" ),
|
||||||
normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ),
|
normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ),
|
||||||
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
|
normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) )
|
||||||
);
|
);
|
||||||
sequenceName = jdbcEnv.getQualifiedObjectNameFormatter().format( qualifiedSequenceName, dialect );
|
sequenceName = jdbcEnvironment.getQualifiedObjectNameFormatter().format( qualifiedSequenceName, dialect );
|
||||||
|
|
||||||
sql = dialect.getSequenceNextValString( sequenceName );
|
sql = dialect.getSequenceNextValString( sequenceName );
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ import java.io.Serializable;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.enhanced.AccessCallback;
|
import org.hibernate.id.enhanced.AccessCallback;
|
||||||
import org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer;
|
import org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,8 +39,8 @@ public class SequenceHiLoGenerator extends SequenceGenerator {
|
||||||
private LegacyHiLoAlgorithmOptimizer hiloOptimizer;
|
private LegacyHiLoAlgorithmOptimizer hiloOptimizer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment d) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
super.configure(type, params, d);
|
super.configure( type, params, serviceRegistry );
|
||||||
|
|
||||||
maxLo = ConfigurationHelper.getInt( MAX_LO, params, 9 );
|
maxLo = ConfigurationHelper.getInt( MAX_LO, params, 9 );
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,12 @@ import java.util.Properties;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.insert.AbstractReturningDelegate;
|
import org.hibernate.id.insert.AbstractReturningDelegate;
|
||||||
import org.hibernate.id.insert.IdentifierGeneratingInsert;
|
import org.hibernate.id.insert.IdentifierGeneratingInsert;
|
||||||
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
|
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.Insert;
|
import org.hibernate.sql.Insert;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ public class SequenceIdentityGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment env) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
super.configure( type, params, env );
|
super.configure( type, params, serviceRegistry );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Delegate extends AbstractReturningDelegate {
|
public static class Delegate extends AbstractReturningDelegate {
|
||||||
|
|
|
@ -12,12 +12,13 @@ import java.util.UUID;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.uuid.StandardRandomStrategy;
|
import org.hibernate.id.uuid.StandardRandomStrategy;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ public class UUIDGenerator implements IdentifierGenerator, Configurable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
// check first for the strategy instance
|
// check first for the strategy instance
|
||||||
strategy = (UUIDGenerationStrategy) params.get( UUID_GEN_STRATEGY );
|
strategy = (UUIDGenerationStrategy) params.get( UUID_GEN_STRATEGY );
|
||||||
if ( strategy == null ) {
|
if ( strategy == null ) {
|
||||||
|
@ -63,7 +64,8 @@ public class UUIDGenerator implements IdentifierGenerator, Configurable {
|
||||||
final String strategyClassName = params.getProperty( UUID_GEN_STRATEGY_CLASS );
|
final String strategyClassName = params.getProperty( UUID_GEN_STRATEGY_CLASS );
|
||||||
if ( strategyClassName != null ) {
|
if ( strategyClassName != null ) {
|
||||||
try {
|
try {
|
||||||
final Class strategyClass = ReflectHelper.classForName( strategyClassName );
|
final ClassLoaderService cls = serviceRegistry.getService( ClassLoaderService.class );
|
||||||
|
final Class strategyClass = cls.classForName( strategyClassName );
|
||||||
try {
|
try {
|
||||||
strategy = (UUIDGenerationStrategy) strategyClass.newInstance();
|
strategy = (UUIDGenerationStrategy) strategyClass.newInstance();
|
||||||
}
|
}
|
||||||
|
@ -71,8 +73,8 @@ public class UUIDGenerator implements IdentifierGenerator, Configurable {
|
||||||
LOG.unableToInstantiateUuidGenerationStrategy(ignore);
|
LOG.unableToInstantiateUuidGenerationStrategy(ignore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException ignore ) {
|
catch ( ClassLoadingException ignore ) {
|
||||||
LOG.unableToLocateUuidGenerationStrategy(strategyClassName);
|
LOG.unableToLocateUuidGenerationStrategy( strategyClassName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ import java.io.Serializable;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configura
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
sep = ConfigurationHelper.getString( "separator", params, "" );
|
sep = ConfigurationHelper.getString( "separator", params, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.id.Configurable;
|
||||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
@ -213,13 +214,14 @@ public class SequenceStyleGenerator
|
||||||
// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
final Dialect dialect = jdbcEnv.getDialect();
|
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||||
|
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||||
|
|
||||||
this.identifierType = type;
|
this.identifierType = type;
|
||||||
boolean forceTableUse = ConfigurationHelper.getBoolean( FORCE_TBL_PARAM, params, false );
|
boolean forceTableUse = ConfigurationHelper.getBoolean( FORCE_TBL_PARAM, params, false );
|
||||||
|
|
||||||
final QualifiedName sequenceName = determineSequenceName( params, dialect, jdbcEnv );
|
final QualifiedName sequenceName = determineSequenceName( params, dialect, jdbcEnvironment );
|
||||||
|
|
||||||
final int initialValue = determineInitialValue( params );
|
final int initialValue = determineInitialValue( params );
|
||||||
int incrementSize = determineIncrementSize( params );
|
int incrementSize = determineIncrementSize( params );
|
||||||
|
@ -237,7 +239,7 @@ public class SequenceStyleGenerator
|
||||||
this.databaseStructure = buildDatabaseStructure(
|
this.databaseStructure = buildDatabaseStructure(
|
||||||
type,
|
type,
|
||||||
params,
|
params,
|
||||||
jdbcEnv,
|
jdbcEnvironment,
|
||||||
forceTableUse,
|
forceTableUse,
|
||||||
sequenceName,
|
sequenceName,
|
||||||
initialValue,
|
initialValue,
|
||||||
|
@ -260,7 +262,7 @@ public class SequenceStyleGenerator
|
||||||
*
|
*
|
||||||
* @param params The params supplied in the generator config (plus some standard useful extras).
|
* @param params The params supplied in the generator config (plus some standard useful extras).
|
||||||
* @param dialect The dialect in effect
|
* @param dialect The dialect in effect
|
||||||
* @param jdbcEnv
|
* @param jdbcEnv The JdbcEnvironment
|
||||||
* @return The sequence name
|
* @return The sequence name
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("UnusedParameters")
|
@SuppressWarnings("UnusedParameters")
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.jdbc.AbstractReturningWork;
|
||||||
import org.hibernate.mapping.Column;
|
import org.hibernate.mapping.Column;
|
||||||
import org.hibernate.mapping.PrimaryKey;
|
import org.hibernate.mapping.PrimaryKey;
|
||||||
import org.hibernate.mapping.Table;
|
import org.hibernate.mapping.Table;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.LongType;
|
import org.hibernate.type.LongType;
|
||||||
import org.hibernate.type.StringType;
|
import org.hibernate.type.StringType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -344,13 +345,14 @@ public class TableGenerator implements PersistentIdentifierGenerator, Configurab
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Type type, Properties params, JdbcEnvironment jdbcEnv) throws MappingException {
|
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||||
identifierType = type;
|
identifierType = type;
|
||||||
|
|
||||||
final Dialect dialect = jdbcEnv.getDialect();
|
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||||
|
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||||
|
|
||||||
qualifiedTableName = determineGeneratorTableName( params, dialect );
|
qualifiedTableName = determineGeneratorTableName( params, dialect );
|
||||||
renderedTableName = jdbcEnv.getQualifiedObjectNameFormatter().format( qualifiedTableName, dialect );
|
renderedTableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format( qualifiedTableName, dialect );
|
||||||
segmentColumnName = determineSegmentColumnName( params, dialect );
|
segmentColumnName = determineSegmentColumnName( params, dialect );
|
||||||
valueColumnName = determineValueColumnName( params, dialect );
|
valueColumnName = determineValueColumnName( params, dialect );
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.Properties;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||||
import org.hibernate.id.Assigned;
|
import org.hibernate.id.Assigned;
|
||||||
|
@ -31,7 +33,7 @@ import org.hibernate.id.enhanced.TableGenerator;
|
||||||
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
|
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -46,12 +48,15 @@ public class DefaultIdentifierGeneratorFactory
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultIdentifierGeneratorFactory.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( DefaultIdentifierGeneratorFactory.class );
|
||||||
|
|
||||||
private JdbcEnvironment jdbcEnvironment;
|
private ServiceRegistry serviceRegistry;
|
||||||
|
private Dialect dialect;
|
||||||
|
|
||||||
private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>();
|
private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DefaultIdentifierGeneratorFactory.
|
* Constructs a new DefaultIdentifierGeneratorFactory.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public DefaultIdentifierGeneratorFactory() {
|
public DefaultIdentifierGeneratorFactory() {
|
||||||
register( "uuid2", UUIDGenerator.class );
|
register( "uuid2", UUIDGenerator.class );
|
||||||
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
|
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
|
||||||
|
@ -79,7 +84,7 @@ public class DefaultIdentifierGeneratorFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dialect getDialect() {
|
public Dialect getDialect() {
|
||||||
return jdbcEnvironment.getDialect();
|
return dialect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,7 +112,7 @@ public class DefaultIdentifierGeneratorFactory
|
||||||
Class clazz = getIdentifierGeneratorClass( strategy );
|
Class clazz = getIdentifierGeneratorClass( strategy );
|
||||||
IdentifierGenerator identifierGenerator = ( IdentifierGenerator ) clazz.newInstance();
|
IdentifierGenerator identifierGenerator = ( IdentifierGenerator ) clazz.newInstance();
|
||||||
if ( identifierGenerator instanceof Configurable ) {
|
if ( identifierGenerator instanceof Configurable ) {
|
||||||
( ( Configurable ) identifierGenerator ).configure( type, config, jdbcEnvironment );
|
( ( Configurable ) identifierGenerator ).configure( type, config, serviceRegistry );
|
||||||
}
|
}
|
||||||
return identifierGenerator;
|
return identifierGenerator;
|
||||||
}
|
}
|
||||||
|
@ -130,10 +135,11 @@ public class DefaultIdentifierGeneratorFactory
|
||||||
Class generatorClass = generatorStrategyToClassNameMap.get( strategy );
|
Class generatorClass = generatorStrategyToClassNameMap.get( strategy );
|
||||||
try {
|
try {
|
||||||
if ( generatorClass == null ) {
|
if ( generatorClass == null ) {
|
||||||
generatorClass = ReflectHelper.classForName( strategy );
|
final ClassLoaderService cls = serviceRegistry.getService( ClassLoaderService.class );
|
||||||
|
generatorClass = cls.classForName( strategy );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException e ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
|
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
|
||||||
}
|
}
|
||||||
return generatorClass;
|
return generatorClass;
|
||||||
|
@ -141,6 +147,7 @@ public class DefaultIdentifierGeneratorFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||||
this.jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
this.dialect = serviceRegistry.getService( JdbcEnvironment.class ).getDialect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,11 @@ import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.engine.spi.TypedValue;
|
import org.hibernate.engine.spi.TypedValue;
|
||||||
import org.hibernate.hql.internal.classic.ParserHelper;
|
import org.hibernate.hql.internal.classic.ParserHelper;
|
||||||
import org.hibernate.internal.util.MarkerObject;
|
import org.hibernate.internal.util.MarkerObject;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.access.spi.BuiltInPropertyAccessStrategies;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
import org.hibernate.proxy.HibernateProxyHelper;
|
import org.hibernate.proxy.HibernateProxyHelper;
|
||||||
import org.hibernate.transform.ResultTransformer;
|
import org.hibernate.transform.ResultTransformer;
|
||||||
import org.hibernate.type.SerializableType;
|
import org.hibernate.type.SerializableType;
|
||||||
|
@ -917,8 +918,12 @@ public abstract class AbstractQueryImpl implements Query {
|
||||||
String[] params = getNamedParameters();
|
String[] params = getNamedParameters();
|
||||||
for ( String namedParam : params ) {
|
for ( String namedParam : params ) {
|
||||||
try {
|
try {
|
||||||
Getter getter = ReflectHelper.getGetter( clazz, namedParam );
|
final PropertyAccess propertyAccess = BuiltInPropertyAccessStrategies.BASIC.getStrategy().buildPropertyAccess(
|
||||||
Class retType = getter.getReturnType();
|
clazz,
|
||||||
|
namedParam
|
||||||
|
);
|
||||||
|
final Getter getter = propertyAccess.getGetter();
|
||||||
|
final Class retType = getter.getReturnType();
|
||||||
final Object object = getter.get( bean );
|
final Object object = getter.get( bean );
|
||||||
if ( Collection.class.isAssignableFrom( retType ) ) {
|
if ( Collection.class.isAssignableFrom( retType ) ) {
|
||||||
setParameterList( namedParam, (Collection) object );
|
setParameterList( namedParam, (Collection) object );
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.internal.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This exists purely to allow custom ClassLoaders to be injected and used
|
|
||||||
* prior to ServiceRegistry and ClassLoadingService existence. This should be
|
|
||||||
* replaced in Hibernate 5.
|
|
||||||
*
|
|
||||||
* @author Brett Meyer
|
|
||||||
*/
|
|
||||||
public final class ClassLoaderHelper {
|
|
||||||
private ClassLoaderHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassLoader overridenClassLoader;
|
|
||||||
|
|
||||||
public static ClassLoader getContextClassLoader() {
|
|
||||||
return overridenClassLoader != null ?
|
|
||||||
overridenClassLoader : Thread.currentThread().getContextClassLoader();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,11 +8,8 @@ package org.hibernate.internal.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
@ -23,8 +20,10 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
* A simple class to centralize logic needed to locate config files on the system.
|
* A simple class to centralize logic needed to locate config files on the system.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @todo : Update usages to use {@link org.hibernate.boot.registry.classloading.spi.ClassLoaderService}
|
*
|
||||||
|
* @deprecated Use {@link org.hibernate.boot.registry.classloading.spi.ClassLoaderService} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class ConfigHelper {
|
public final class ConfigHelper {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( ConfigHelper.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( ConfigHelper.class );
|
||||||
|
|
||||||
|
@ -61,7 +60,7 @@ public final class ConfigHelper {
|
||||||
|
|
||||||
// First, try to locate this resource through the current
|
// First, try to locate this resource through the current
|
||||||
// context classloader.
|
// context classloader.
|
||||||
ClassLoader contextClassLoader = ClassLoaderHelper.getContextClassLoader();
|
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if ( contextClassLoader != null ) {
|
if ( contextClassLoader != null ) {
|
||||||
url = contextClassLoader.getResource( path );
|
url = contextClassLoader.getResource( path );
|
||||||
}
|
}
|
||||||
|
@ -110,42 +109,6 @@ public final class ConfigHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an Reader to the URL represented by the incoming path. First makes a call
|
|
||||||
* to {@link #locateConfig(java.lang.String)} in order to find an appropriate URL.
|
|
||||||
* {@link java.net.URL#openStream()} is then called to obtain a stream, which is then
|
|
||||||
* wrapped in a Reader.
|
|
||||||
*
|
|
||||||
* @param path The path representing the config location.
|
|
||||||
*
|
|
||||||
* @return An input stream to the requested config resource.
|
|
||||||
*
|
|
||||||
* @throws HibernateException Unable to open reader to that resource.
|
|
||||||
*/
|
|
||||||
public static Reader getConfigStreamReader(final String path) throws HibernateException {
|
|
||||||
return new InputStreamReader( getConfigStream( path ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a properties instance based on the data at the incoming config location.
|
|
||||||
*
|
|
||||||
* @param path The path representing the config location.
|
|
||||||
*
|
|
||||||
* @return The loaded properties instance.
|
|
||||||
*
|
|
||||||
* @throws HibernateException Unable to load properties from that resource.
|
|
||||||
*/
|
|
||||||
public static Properties getConfigProperties(String path) throws HibernateException {
|
|
||||||
try {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.load( getConfigStream( path ) );
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new HibernateException( "Unable to load properties from specified config file: " + path, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigHelper() {
|
private ConfigHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +118,7 @@ public final class ConfigHelper {
|
||||||
: resource;
|
: resource;
|
||||||
|
|
||||||
InputStream stream = null;
|
InputStream stream = null;
|
||||||
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if ( classLoader != null ) {
|
if ( classLoader != null ) {
|
||||||
stream = classLoader.getResourceAsStream( stripped );
|
stream = classLoader.getResourceAsStream( stripped );
|
||||||
}
|
}
|
||||||
|
@ -178,7 +141,7 @@ public final class ConfigHelper {
|
||||||
|
|
||||||
InputStream stream = null;
|
InputStream stream = null;
|
||||||
|
|
||||||
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if ( classLoader != null ) {
|
if ( classLoader != null ) {
|
||||||
stream = classLoader.getResourceAsStream( resource );
|
stream = classLoader.getResourceAsStream( resource );
|
||||||
if ( stream == null && hasLeadingSlash ) {
|
if ( stream == null && hasLeadingSlash ) {
|
||||||
|
|
|
@ -6,18 +6,21 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.internal.util;
|
package org.hibernate.internal.util;
|
||||||
|
|
||||||
|
import java.beans.Introspector;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.PropertyNotFoundException;
|
import org.hibernate.PropertyNotFoundException;
|
||||||
import org.hibernate.property.BasicPropertyAccessor;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.property.DirectPropertyAccessor;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyMixedImpl;
|
||||||
import org.hibernate.property.PropertyAccessor;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.type.PrimitiveType;
|
import org.hibernate.type.PrimitiveType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -29,11 +32,6 @@ import org.hibernate.type.Type;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final class ReflectHelper {
|
public final class ReflectHelper {
|
||||||
|
|
||||||
//TODO: this dependency is kinda Bad
|
|
||||||
private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
|
|
||||||
private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
|
|
||||||
|
|
||||||
public static final Class[] NO_PARAM_SIGNATURE = new Class[0];
|
public static final Class[] NO_PARAM_SIGNATURE = new Class[0];
|
||||||
public static final Object[] NO_PARAMS = new Object[0];
|
public static final Object[] NO_PARAMS = new Object[0];
|
||||||
|
|
||||||
|
@ -143,7 +141,7 @@ public final class ReflectHelper {
|
||||||
*/
|
*/
|
||||||
public static Class classForName(String name, Class caller) throws ClassNotFoundException {
|
public static Class classForName(String name, Class caller) throws ClassNotFoundException {
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if ( classLoader != null ) {
|
if ( classLoader != null ) {
|
||||||
return classLoader.loadClass( name );
|
return classLoader.loadClass( name );
|
||||||
}
|
}
|
||||||
|
@ -161,11 +159,16 @@ public final class ReflectHelper {
|
||||||
*
|
*
|
||||||
* @param name The class name
|
* @param name The class name
|
||||||
* @return The class reference.
|
* @return The class reference.
|
||||||
|
*
|
||||||
* @throws ClassNotFoundException From {@link Class#forName(String)}.
|
* @throws ClassNotFoundException From {@link Class#forName(String)}.
|
||||||
|
*
|
||||||
|
* @deprecated Depending on context, either {@link org.hibernate.boot.registry.classloading.spi.ClassLoaderService}
|
||||||
|
* or {@link org.hibernate.boot.spi.ClassLoaderAccess} should be preferred
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static Class classForName(String name) throws ClassNotFoundException {
|
public static Class classForName(String name) throws ClassNotFoundException {
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = ClassLoaderHelper.getContextClassLoader();
|
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if ( classLoader != null ) {
|
if ( classLoader != null ) {
|
||||||
return classLoader.loadClass(name);
|
return classLoader.loadClass(name);
|
||||||
}
|
}
|
||||||
|
@ -175,18 +178,6 @@ public final class ReflectHelper {
|
||||||
return Class.forName( name );
|
return Class.forName( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this member publicly accessible.
|
|
||||||
* <p/>
|
|
||||||
* Short-hand for {@link #isPublic(Class, Member)} passing the member + {@link Member#getDeclaringClass()}
|
|
||||||
*
|
|
||||||
* @param member The member to check
|
|
||||||
* @return True if the member is publicly accessible.
|
|
||||||
*/
|
|
||||||
public static boolean isPublic(Member member) {
|
|
||||||
return isPublic( member.getDeclaringClass(), member );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this member publicly accessible.
|
* Is this member publicly accessible.
|
||||||
*
|
*
|
||||||
|
@ -203,16 +194,22 @@ public final class ReflectHelper {
|
||||||
*
|
*
|
||||||
* @param className The name of the class owning the property.
|
* @param className The name of the class owning the property.
|
||||||
* @param name The name of the property.
|
* @param name The name of the property.
|
||||||
|
* @param classLoaderService ClassLoader services
|
||||||
|
*
|
||||||
* @return The type of the property.
|
* @return The type of the property.
|
||||||
|
*
|
||||||
* @throws MappingException Indicates we were unable to locate the property.
|
* @throws MappingException Indicates we were unable to locate the property.
|
||||||
*/
|
*/
|
||||||
public static Class reflectedPropertyClass(String className, String name) throws MappingException {
|
public static Class reflectedPropertyClass(
|
||||||
|
String className,
|
||||||
|
String name,
|
||||||
|
ClassLoaderService classLoaderService) throws MappingException {
|
||||||
try {
|
try {
|
||||||
Class clazz = ReflectHelper.classForName( className );
|
Class clazz = classLoaderService.classForName( className );
|
||||||
return getter( clazz, name ).getReturnType();
|
return getter( clazz, name ).getReturnType();
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException cnfe ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new MappingException( "class " + className + " not found while looking for property: " + name, cnfe );
|
throw new MappingException( "class " + className + " not found while looking for property: " + name, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,36 +226,13 @@ public final class ReflectHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Getter getter(Class clazz, String name) throws MappingException {
|
private static Getter getter(Class clazz, String name) throws MappingException {
|
||||||
try {
|
return PropertyAccessStrategyMixedImpl.INSTANCE.buildPropertyAccess( clazz, name ).getGetter();
|
||||||
return BASIC_PROPERTY_ACCESSOR.getGetter( clazz, name );
|
|
||||||
}
|
|
||||||
catch ( PropertyNotFoundException pnfe ) {
|
|
||||||
return DIRECT_PROPERTY_ACCESSOR.getGetter( clazz, name );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Object getConstantValue(String name, ClassLoaderService classLoaderService) {
|
||||||
* Directly retrieve the {@link Getter} reference via the {@link BasicPropertyAccessor}.
|
|
||||||
*
|
|
||||||
* @param theClass The class owning the property
|
|
||||||
* @param name The name of the property
|
|
||||||
* @return The getter.
|
|
||||||
* @throws MappingException Indicates we were unable to locate the property.
|
|
||||||
*/
|
|
||||||
public static Getter getGetter(Class theClass, String name) throws MappingException {
|
|
||||||
return BASIC_PROPERTY_ACCESSOR.getGetter( theClass, name );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve a constant to its actual value.
|
|
||||||
*
|
|
||||||
* @param name The name
|
|
||||||
* @return The value
|
|
||||||
*/
|
|
||||||
public static Object getConstantValue(String name) {
|
|
||||||
Class clazz;
|
Class clazz;
|
||||||
try {
|
try {
|
||||||
clazz = classForName( StringHelper.qualifier( name ) );
|
clazz = classLoaderService.classForName( StringHelper.qualifier( name ) );
|
||||||
}
|
}
|
||||||
catch ( Throwable t ) {
|
catch ( Throwable t ) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -327,15 +301,14 @@ public final class ReflectHelper {
|
||||||
*/
|
*/
|
||||||
public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
|
public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
|
||||||
final Constructor[] candidates = clazz.getConstructors();
|
final Constructor[] candidates = clazz.getConstructors();
|
||||||
for ( int i = 0; i < candidates.length; i++ ) {
|
for ( final Constructor constructor : candidates ) {
|
||||||
final Constructor constructor = candidates[i];
|
|
||||||
final Class[] params = constructor.getParameterTypes();
|
final Class[] params = constructor.getParameterTypes();
|
||||||
if ( params.length == types.length ) {
|
if ( params.length == types.length ) {
|
||||||
boolean found = true;
|
boolean found = true;
|
||||||
for ( int j = 0; j < params.length; j++ ) {
|
for ( int j = 0; j < params.length; j++ ) {
|
||||||
final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
|
final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
|
||||||
types[j] instanceof PrimitiveType &&
|
types[j] instanceof PrimitiveType &&
|
||||||
params[j] == ( ( PrimitiveType ) types[j] ).getPrimitiveClass()
|
params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
|
||||||
);
|
);
|
||||||
if ( !ok ) {
|
if ( !ok ) {
|
||||||
found = false;
|
found = false;
|
||||||
|
@ -360,4 +333,175 @@ public final class ReflectHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Field findField(Class containerClass, String propertyName) {
|
||||||
|
if ( containerClass == null ) {
|
||||||
|
throw new IllegalArgumentException( "Class on which to find field [" + propertyName + "] cannot be null" );
|
||||||
|
}
|
||||||
|
else if ( containerClass == Object.class ) {
|
||||||
|
throw new IllegalArgumentException( "Illegal attempt to locate field [" + propertyName + "] on Object.class" );
|
||||||
|
}
|
||||||
|
|
||||||
|
Field field = locateField( containerClass, propertyName );
|
||||||
|
|
||||||
|
if ( field == null ) {
|
||||||
|
throw new PropertyNotFoundException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Could not locate field name [%s] on class [%s]",
|
||||||
|
propertyName,
|
||||||
|
containerClass.getName()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
field.setAccessible( true );
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field locateField(Class clazz, String propertyName) {
|
||||||
|
if ( clazz == null || Object.class.equals( clazz ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return clazz.getDeclaredField( propertyName );
|
||||||
|
}
|
||||||
|
catch ( NoSuchFieldException nsfe ) {
|
||||||
|
return locateField( clazz.getSuperclass(), propertyName );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findGetterMethod(Class containerClass, String propertyName) {
|
||||||
|
Class checkClass = containerClass;
|
||||||
|
Method getter = null;
|
||||||
|
|
||||||
|
// check containerClass, and then its super types (if any)
|
||||||
|
while ( getter == null && checkClass != null ) {
|
||||||
|
if ( checkClass.equals( Object.class ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
getter = getGetterOrNull( checkClass, propertyName );
|
||||||
|
checkClass = checkClass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no getter found yet, check all implemented interfaces
|
||||||
|
if ( getter == null ) {
|
||||||
|
for ( Class theInterface : containerClass.getInterfaces() ) {
|
||||||
|
getter = getGetterOrNull( theInterface, propertyName );
|
||||||
|
if ( getter != null ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getter == null ) {
|
||||||
|
throw new PropertyNotFoundException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Could not locate getter method for property [%s#%s]",
|
||||||
|
containerClass.getName(),
|
||||||
|
propertyName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getter.setAccessible( true );
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method getGetterOrNull(Class containerClass, String propertyName) {
|
||||||
|
for ( Method method : containerClass.getDeclaredMethods() ) {
|
||||||
|
// if the method has parameters, skip it
|
||||||
|
if ( method.getParameterTypes().length != 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the method is a "bridge", skip it
|
||||||
|
if ( method.isBridge() ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String methodName = method.getName();
|
||||||
|
|
||||||
|
// try "get"
|
||||||
|
if ( methodName.startsWith( "get" ) ) {
|
||||||
|
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
|
||||||
|
String testOldMethod = methodName.substring( 3 );
|
||||||
|
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not "get", then try "is"
|
||||||
|
if ( methodName.startsWith( "is" ) ) {
|
||||||
|
String testStdMethod = Introspector.decapitalize( methodName.substring( 2 ) );
|
||||||
|
String testOldMethod = methodName.substring( 2 );
|
||||||
|
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Method findSetterMethod(Class containerClass, String propertyName, Class propertyType) {
|
||||||
|
Class checkClass = containerClass;
|
||||||
|
Method setter = null;
|
||||||
|
|
||||||
|
// check containerClass, and then its super types (if any)
|
||||||
|
while ( setter == null && checkClass != null ) {
|
||||||
|
if ( checkClass.equals( Object.class ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setter = setterOrNull( checkClass, propertyName, propertyType );
|
||||||
|
checkClass = checkClass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no setter found yet, check all implemented interfaces
|
||||||
|
if ( setter == null ) {
|
||||||
|
for ( Class theInterface : containerClass.getInterfaces() ) {
|
||||||
|
setter = setterOrNull( theInterface, propertyName, propertyType );
|
||||||
|
if ( setter != null ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( setter == null ) {
|
||||||
|
throw new PropertyNotFoundException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Could not locate setter method for property [%s#%s]",
|
||||||
|
containerClass.getName(),
|
||||||
|
propertyName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setter.setAccessible( true );
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method setterOrNull(Class theClass, String propertyName, Class propertyType) {
|
||||||
|
Method potentialSetter = null;
|
||||||
|
|
||||||
|
for ( Method method : theClass.getDeclaredMethods() ) {
|
||||||
|
final String methodName = method.getName();
|
||||||
|
if ( method.getParameterTypes().length == 1 && methodName.startsWith( "set" ) ) {
|
||||||
|
final String testOldMethod = methodName.substring( 3 );
|
||||||
|
final String testStdMethod = Introspector.decapitalize( testOldMethod );
|
||||||
|
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
||||||
|
potentialSetter = method;
|
||||||
|
if ( propertyType == null || method.getParameterTypes()[0].equals( propertyType ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return potentialSetter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ public final class SerializationHelper {
|
||||||
* @return The current TCCL
|
* @return The current TCCL
|
||||||
*/
|
*/
|
||||||
public static ClassLoader defaultClassLoader() {
|
public static ClassLoader defaultClassLoader() {
|
||||||
return ClassLoaderHelper.getContextClassLoader();
|
return Thread.currentThread().getContextClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassLoader hibernateClassLoader() {
|
public static ClassLoader hibernateClassLoader() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.internal.util.xml;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.internal.stax.*;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ConfigHelper;
|
import org.hibernate.internal.util.ConfigHelper;
|
||||||
|
|
||||||
|
@ -37,7 +38,11 @@ import org.xml.sax.InputSource;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
|
*
|
||||||
|
* @deprecated Hibernate now uses StAX for XML processing and the role of this class is served
|
||||||
|
* now by {@link org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class DTDEntityResolver implements EntityResolver, Serializable {
|
public class DTDEntityResolver implements EntityResolver, Serializable {
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, DTDEntityResolver.class.getName() );
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, DTDEntityResolver.class.getName() );
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.internal.util.xml;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
import org.hibernate.internal.util.ConfigHelper;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class LocalXmlResourceResolver implements javax.xml.stream.XMLResolver {
|
|
||||||
private static final CoreMessageLogger log = Logger.getMessageLogger(
|
|
||||||
CoreMessageLogger.class,
|
|
||||||
MappingReader.class.getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final LocalXmlResourceResolver INSTANCE = new LocalXmlResourceResolver();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespace for the orm.xml xsd for jpa 1.0 and 2.0
|
|
||||||
*/
|
|
||||||
public static final String INITIAL_JPA_ORM_NS = "http://java.sun.com/xml/ns/persistence/orm";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespace for the orm.xml xsd for jpa 2.1
|
|
||||||
*/
|
|
||||||
public static final String SECOND_JPA_ORM_NS = "http://xmlns.jcp.org/xml/ns/persistence/orm";
|
|
||||||
|
|
||||||
public static final String HIBERNATE_MAPPING_DTD_URL_BASE = "http://www.hibernate.org/dtd/";
|
|
||||||
public static final String LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE = "http://hibernate.sourceforge.net/";
|
|
||||||
public static final String CLASSPATH_EXTENSION_URL_BASE = "classpath://";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
|
|
||||||
log.tracef( "In resolveEntity(%s, %s, %s, %s)", publicID, systemID, baseURI, namespace );
|
|
||||||
|
|
||||||
if ( namespace != null ) {
|
|
||||||
log.debugf( "Interpreting namespace : %s", namespace );
|
|
||||||
if ( INITIAL_JPA_ORM_NS.equals( namespace ) ) {
|
|
||||||
return openUrlStream( MappingReader.SupportedOrmXsdVersion.ORM_2_0.getSchemaUrl() );
|
|
||||||
}
|
|
||||||
else if ( SECOND_JPA_ORM_NS.equals( namespace ) ) {
|
|
||||||
return openUrlStream( MappingReader.SupportedOrmXsdVersion.ORM_2_1.getSchemaUrl() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( systemID != null ) {
|
|
||||||
log.debugf( "Interpreting systemID : %s", namespace );
|
|
||||||
InputStream stream = null;
|
|
||||||
if ( systemID.startsWith( HIBERNATE_MAPPING_DTD_URL_BASE ) ) {
|
|
||||||
log.debug( "Recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/" );
|
|
||||||
stream = resolveOnClassPath( systemID, HIBERNATE_MAPPING_DTD_URL_BASE );
|
|
||||||
}
|
|
||||||
else if ( systemID.startsWith( LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE ) ) {
|
|
||||||
log.recognizedObsoleteHibernateNamespace( LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE, HIBERNATE_MAPPING_DTD_URL_BASE );
|
|
||||||
log.debug( "Attempting to resolve on classpath under org/hibernate/" );
|
|
||||||
stream = resolveOnClassPath( systemID, LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE );
|
|
||||||
}
|
|
||||||
else if ( systemID.startsWith( CLASSPATH_EXTENSION_URL_BASE ) ) {
|
|
||||||
log.debug( "Recognized local namespace; attempting to resolve on classpath" );
|
|
||||||
final String path = systemID.substring( CLASSPATH_EXTENSION_URL_BASE.length() );
|
|
||||||
stream = resolveInLocalNamespace( path );
|
|
||||||
if ( stream == null ) {
|
|
||||||
log.debugf( "Unable to resolve [%s] on classpath", systemID );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.debugf( "Resolved [%s] on classpath", systemID );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( stream != null ) {
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream openUrlStream(URL url) {
|
|
||||||
try {
|
|
||||||
return url.openStream();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new XmlInfrastructureException( "Could not open url stream : " + url.toExternalForm(), e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream resolveOnClassPath(String systemID, String namespace) {
|
|
||||||
final String relativeResourceName = systemID.substring( namespace.length() );
|
|
||||||
final String path = "org/hibernate/" + relativeResourceName;
|
|
||||||
InputStream dtdStream = resolveInHibernateNamespace( path );
|
|
||||||
if ( dtdStream == null ) {
|
|
||||||
log.debugf( "Unable to locate [%s] on classpath", systemID );
|
|
||||||
if ( relativeResourceName.contains( "2.0" ) ) {
|
|
||||||
log.usingOldDtd();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.debugf( "Located [%s] in classpath", systemID );
|
|
||||||
return dtdStream;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream resolveInHibernateNamespace(String path) {
|
|
||||||
return this.getClass().getClassLoader().getResourceAsStream( path );
|
|
||||||
}
|
|
||||||
|
|
||||||
private InputStream resolveInLocalNamespace(String path) {
|
|
||||||
try {
|
|
||||||
return ConfigHelper.getUserResourceAsStream( path );
|
|
||||||
}
|
|
||||||
catch ( Throwable t ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,383 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.internal.util.xml;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import javax.xml.XMLConstants;
|
|
||||||
import javax.xml.namespace.QName;
|
|
||||||
import javax.xml.stream.XMLEventReader;
|
|
||||||
import javax.xml.stream.XMLInputFactory;
|
|
||||||
import javax.xml.stream.XMLStreamConstants;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
import javax.xml.stream.events.Attribute;
|
|
||||||
import javax.xml.stream.events.XMLEvent;
|
|
||||||
import javax.xml.transform.stax.StAXSource;
|
|
||||||
import javax.xml.transform.stream.StreamSource;
|
|
||||||
import javax.xml.validation.Schema;
|
|
||||||
import javax.xml.validation.SchemaFactory;
|
|
||||||
import javax.xml.validation.Validator;
|
|
||||||
|
|
||||||
import org.hibernate.InvalidMappingException;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.dom4j.Document;
|
|
||||||
import org.dom4j.io.SAXReader;
|
|
||||||
import org.dom4j.io.STAXEventReader;
|
|
||||||
import org.xml.sax.EntityResolver;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles reading mapping documents, both {@code hbm} and {@code orm} varieties.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public class MappingReader {
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
|
||||||
CoreMessageLogger.class,
|
|
||||||
MappingReader.class.getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final MappingReader INSTANCE = new MappingReader();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disallow direct instantiation.
|
|
||||||
* <p/>
|
|
||||||
* Eventually we perhaps need to have this configurable by the "configuration" and simply reference it
|
|
||||||
* from there (registry). This would allow, for example, injection of the entity resolver to use as
|
|
||||||
* instance state.
|
|
||||||
*/
|
|
||||||
private MappingReader() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public XmlDocument readMappingDocument(InputSource source, Origin origin) {
|
|
||||||
XMLEventReader staxReader = buildStaxEventReader( source, origin );
|
|
||||||
try {
|
|
||||||
return read( staxReader, origin );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
staxReader.close();
|
|
||||||
}
|
|
||||||
catch ( Exception ignore ) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private XMLEventReader buildStaxEventReader(InputSource source, Origin origin) {
|
|
||||||
XMLEventReader reader = null;
|
|
||||||
|
|
||||||
if ( source.getByteStream() != null ) {
|
|
||||||
try {
|
|
||||||
reader = staxFactory().createXMLEventReader( source.getByteStream() );
|
|
||||||
}
|
|
||||||
catch (XMLStreamException e) {
|
|
||||||
throw new XmlInfrastructureException(
|
|
||||||
"Unable to create stax reader, origin = " + toLoggableString( origin ),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( source.getCharacterStream() != null ) {
|
|
||||||
try {
|
|
||||||
reader = staxFactory().createXMLEventReader( source.getCharacterStream() );
|
|
||||||
}
|
|
||||||
catch (XMLStreamException e) {
|
|
||||||
throw new XmlInfrastructureException(
|
|
||||||
"Unable to create stax reader, origin = " + toLoggableString( origin ),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// todo : try to interpret the InputSource SystemId or Origin path?
|
|
||||||
|
|
||||||
if ( reader == null ) {
|
|
||||||
throw new XmlInfrastructureException( "Unable to convert SAX InputStream into StAX XMLEventReader" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// For performance we wrap the reader in a buffered reader
|
|
||||||
return new BufferedXMLEventReader( reader );
|
|
||||||
}
|
|
||||||
|
|
||||||
private XMLInputFactory staxFactory;
|
|
||||||
|
|
||||||
private XMLInputFactory staxFactory() {
|
|
||||||
if ( staxFactory == null ) {
|
|
||||||
staxFactory = buildStaxFactory();
|
|
||||||
}
|
|
||||||
return staxFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings( { "UnnecessaryLocalVariable" })
|
|
||||||
private XMLInputFactory buildStaxFactory() {
|
|
||||||
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
|
|
||||||
staxFactory.setXMLResolver( LocalXmlResourceResolver.INSTANCE );
|
|
||||||
return staxFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toLoggableString(Origin origin) {
|
|
||||||
return "[type=" + origin.getType() + ", name=" + origin.getName() + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final QName ORM_VERSION_ATTRIBUTE_QNAME = new QName( "version" );
|
|
||||||
|
|
||||||
private XmlDocument read(XMLEventReader staxEventReader, Origin origin) {
|
|
||||||
XMLEvent event;
|
|
||||||
try {
|
|
||||||
event = staxEventReader.peek();
|
|
||||||
while ( event != null && !event.isStartElement() ) {
|
|
||||||
staxEventReader.nextEvent();
|
|
||||||
event = staxEventReader.peek();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new InvalidMappingException( "Error accessing stax stream", origin, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( event == null ) {
|
|
||||||
throw new InvalidMappingException( "Could not locate root element", origin );
|
|
||||||
}
|
|
||||||
|
|
||||||
final String rootElementName = event.asStartElement().getName().getLocalPart();
|
|
||||||
|
|
||||||
if ( "entity-mappings".equals( rootElementName ) ) {
|
|
||||||
final Attribute attribute = event.asStartElement().getAttributeByName( ORM_VERSION_ATTRIBUTE_QNAME );
|
|
||||||
final String explicitVersion = attribute == null ? null : attribute.getValue();
|
|
||||||
validateMapping(
|
|
||||||
SupportedOrmXsdVersion.parse( explicitVersion, origin ),
|
|
||||||
staxEventReader,
|
|
||||||
origin
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new XmlDocumentImpl( toDom4jDocument( staxEventReader, origin ), origin );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Document toDom4jDocument(XMLEventReader staxEventReader, Origin origin) {
|
|
||||||
STAXEventReader dom4jStaxEventReader = new STAXEventReader();
|
|
||||||
try {
|
|
||||||
// the dom4j converter class is touchy about comments (aka, comments make it implode)
|
|
||||||
// so wrap the event stream in a filtering stream to filter out comment events
|
|
||||||
staxEventReader = new FilteringXMLEventReader( staxEventReader ) {
|
|
||||||
@Override
|
|
||||||
protected XMLEvent filterEvent(XMLEvent event, boolean peek) {
|
|
||||||
return event.getEventType() == XMLStreamConstants.COMMENT
|
|
||||||
? null
|
|
||||||
: event;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return dom4jStaxEventReader.readDocument( staxEventReader );
|
|
||||||
}
|
|
||||||
catch (XMLStreamException e) {
|
|
||||||
throw new InvalidMappingException( "Unable to read StAX source as dom4j Document for processing", origin, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateMapping(SupportedOrmXsdVersion xsdVersion, XMLEventReader staxEventReader, Origin origin) {
|
|
||||||
final Validator validator = xsdVersion.getSchema().newValidator();
|
|
||||||
final StAXSource staxSource;
|
|
||||||
try {
|
|
||||||
staxSource = new StAXSource( staxEventReader );
|
|
||||||
}
|
|
||||||
catch (XMLStreamException e) {
|
|
||||||
throw new InvalidMappingException( "Unable to generate StAXSource from mapping", origin, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
validator.validate( staxSource );
|
|
||||||
}
|
|
||||||
catch (SAXException e) {
|
|
||||||
throw new InvalidMappingException( "SAXException performing validation", origin, e );
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new InvalidMappingException( "IOException performing validation", origin, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum SupportedOrmXsdVersion {
|
|
||||||
ORM_1_0( "org/hibernate/jpa/orm_1_0.xsd" ),
|
|
||||||
ORM_2_0( "org/hibernate/jpa/orm_2_0.xsd" ),
|
|
||||||
ORM_2_1( "org/hibernate/jpa/orm_2_1.xsd" );
|
|
||||||
|
|
||||||
private final String schemaResourceName;
|
|
||||||
|
|
||||||
private SupportedOrmXsdVersion(String schemaResourceName) {
|
|
||||||
this.schemaResourceName = schemaResourceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SupportedOrmXsdVersion parse(String name, Origin origin) {
|
|
||||||
if ( "1.0".equals( name ) ) {
|
|
||||||
return ORM_1_0;
|
|
||||||
}
|
|
||||||
else if ( "2.0".equals( name ) ) {
|
|
||||||
return ORM_2_0;
|
|
||||||
}
|
|
||||||
else if ( "2.1".equals( name ) ) {
|
|
||||||
return ORM_2_1;
|
|
||||||
}
|
|
||||||
throw new UnsupportedOrmXsdVersionException( name, origin );
|
|
||||||
}
|
|
||||||
|
|
||||||
private URL schemaUrl;
|
|
||||||
|
|
||||||
public URL getSchemaUrl() {
|
|
||||||
if ( schemaUrl == null ) {
|
|
||||||
schemaUrl = resolveLocalSchemaUrl( schemaResourceName );
|
|
||||||
}
|
|
||||||
return schemaUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Schema schema;
|
|
||||||
|
|
||||||
public Schema getSchema() {
|
|
||||||
if ( schema == null ) {
|
|
||||||
schema = resolveLocalSchema( getSchemaUrl() );
|
|
||||||
}
|
|
||||||
return schema;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static URL resolveLocalSchemaUrl(String schemaName) {
|
|
||||||
URL url = MappingReader.class.getClassLoader().getResource( schemaName );
|
|
||||||
if ( url == null ) {
|
|
||||||
throw new XmlInfrastructureException( "Unable to locate schema [" + schemaName + "] via classpath" );
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Schema resolveLocalSchema(URL schemaUrl) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
InputStream schemaStream = schemaUrl.openStream();
|
|
||||||
try {
|
|
||||||
StreamSource source = new StreamSource(schemaUrl.openStream());
|
|
||||||
SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
|
|
||||||
return schemaFactory.newSchema(source);
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new XmlInfrastructureException( "Unable to load schema [" + schemaUrl.toExternalForm() + "]", e );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
schemaStream.close();
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
LOG.debugf( "Problem closing schema stream - %s", e.toString() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
throw new XmlInfrastructureException( "Stream error handling schema url [" + schemaUrl.toExternalForm() + "]" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
|
|
||||||
return legacyReadMappingDocument( entityResolver, source, origin );
|
|
||||||
// return readMappingDocument( source, origin );
|
|
||||||
}
|
|
||||||
|
|
||||||
private XmlDocument legacyReadMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
|
|
||||||
// IMPL NOTE : this is the legacy logic as pulled from the old AnnotationConfiguration code
|
|
||||||
|
|
||||||
Exception failure;
|
|
||||||
|
|
||||||
ErrorLogger errorHandler = new ErrorLogger();
|
|
||||||
|
|
||||||
SAXReader saxReader = new SAXReader();
|
|
||||||
saxReader.setEntityResolver( entityResolver );
|
|
||||||
saxReader.setErrorHandler( errorHandler );
|
|
||||||
saxReader.setMergeAdjacentText( true );
|
|
||||||
saxReader.setValidation( true );
|
|
||||||
|
|
||||||
Document document = null;
|
|
||||||
try {
|
|
||||||
// first try with orm 2.1 xsd validation
|
|
||||||
setValidationFor( saxReader, "orm_2_1.xsd" );
|
|
||||||
document = saxReader.read( source );
|
|
||||||
if ( errorHandler.hasErrors() ) {
|
|
||||||
throw errorHandler.getErrors().get( 0 );
|
|
||||||
}
|
|
||||||
return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
if ( LOG.isDebugEnabled() ) {
|
|
||||||
LOG.debugf( "Problem parsing XML using orm 2.1 xsd, trying 2.0 xsd : %s", e.getMessage() );
|
|
||||||
}
|
|
||||||
failure = e;
|
|
||||||
errorHandler.reset();
|
|
||||||
|
|
||||||
if ( document != null ) {
|
|
||||||
// next try with orm 2.0 xsd validation
|
|
||||||
try {
|
|
||||||
setValidationFor( saxReader, "orm_2_0.xsd" );
|
|
||||||
document = saxReader.read( new StringReader( document.asXML() ) );
|
|
||||||
if ( errorHandler.hasErrors() ) {
|
|
||||||
errorHandler.logErrors();
|
|
||||||
throw errorHandler.getErrors().get( 0 );
|
|
||||||
}
|
|
||||||
return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
|
|
||||||
}
|
|
||||||
catch ( Exception e2 ) {
|
|
||||||
if ( LOG.isDebugEnabled() ) {
|
|
||||||
LOG.debugf( "Problem parsing XML using orm 2.0 xsd, trying 1.0 xsd : %s", e2.getMessage() );
|
|
||||||
}
|
|
||||||
errorHandler.reset();
|
|
||||||
|
|
||||||
if ( document != null ) {
|
|
||||||
// next try with orm 1.0 xsd validation
|
|
||||||
try {
|
|
||||||
setValidationFor( saxReader, "orm_1_0.xsd" );
|
|
||||||
document = saxReader.read( new StringReader( document.asXML() ) );
|
|
||||||
if ( errorHandler.hasErrors() ) {
|
|
||||||
errorHandler.logErrors();
|
|
||||||
throw errorHandler.getErrors().get( 0 );
|
|
||||||
}
|
|
||||||
return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
|
|
||||||
}
|
|
||||||
catch ( Exception e3 ) {
|
|
||||||
if ( LOG.isDebugEnabled() ) {
|
|
||||||
LOG.debugf( "Problem parsing XML using orm 1.0 xsd : %s", e3.getMessage() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new InvalidMappingException( "Unable to read XML", origin.getType(), origin.getName(), failure );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setValidationFor(SAXReader saxReader, String xsd) {
|
|
||||||
try {
|
|
||||||
saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
|
|
||||||
// saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
|
|
||||||
if ( "orm_2_1.xsd".equals( xsd ) ) {
|
|
||||||
saxReader.setProperty(
|
|
||||||
"http://apache.org/xml/properties/schema/external-schemaLocation",
|
|
||||||
"http://xmlns.jcp.org/xml/ns/persistence/orm " + xsd
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
saxReader.setProperty(
|
|
||||||
"http://apache.org/xml/properties/schema/external-schemaLocation",
|
|
||||||
"http://java.sun.com/xml/ns/persistence/orm " + xsd
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( SAXException e ) {
|
|
||||||
saxReader.setValidation( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -6,91 +6,52 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.internal.util.xml;
|
package org.hibernate.internal.util.xml;
|
||||||
|
|
||||||
import org.hibernate.internal.util.ClassLoaderHelper;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
|
||||||
import org.dom4j.DocumentFactory;
|
import org.dom4j.DocumentFactory;
|
||||||
import org.dom4j.Element;
|
|
||||||
import org.dom4j.io.DOMReader;
|
|
||||||
import org.dom4j.io.OutputFormat;
|
|
||||||
import org.dom4j.io.SAXReader;
|
import org.dom4j.io.SAXReader;
|
||||||
import org.dom4j.io.XMLWriter;
|
|
||||||
import org.xml.sax.EntityResolver;
|
import org.xml.sax.EntityResolver;
|
||||||
import org.xml.sax.ErrorHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Small helper class that lazy loads DOM and SAX reader and keep them for fast use afterwards.
|
* Small helper class that lazy loads DOM and SAX reader and keep them for fast use afterwards.
|
||||||
|
*
|
||||||
|
* @deprecated Currently only used for integration with HCANN. The rest of Hibernate uses StAX now
|
||||||
|
* for XML processing. See {@link org.hibernate.boot.jaxb.internal.stax}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class XMLHelper {
|
public final class XMLHelper {
|
||||||
|
private final DocumentFactory documentFactory;
|
||||||
|
|
||||||
public static final EntityResolver DEFAULT_DTD_RESOLVER = new DTDEntityResolver();
|
public XMLHelper(ClassLoaderService classLoaderService) {
|
||||||
|
this.documentFactory = classLoaderService.workWithClassLoader(
|
||||||
|
new ClassLoaderService.Work<DocumentFactory>() {
|
||||||
|
@Override
|
||||||
|
public DocumentFactory doWork(ClassLoader classLoader) {
|
||||||
|
final ClassLoader originalTccl = Thread.currentThread().getContextClassLoader();
|
||||||
|
try {
|
||||||
|
Thread.currentThread().setContextClassLoader( classLoader );
|
||||||
|
return DocumentFactory.getInstance();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Thread.currentThread().setContextClassLoader( originalTccl );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private DOMReader domReader;
|
}
|
||||||
private SAXReader saxReader;
|
|
||||||
|
|
||||||
/**
|
public DocumentFactory getDocumentFactory() {
|
||||||
* @param errorHandler the sax error handler
|
return documentFactory;
|
||||||
* @param entityResolver an xml entity resolver
|
}
|
||||||
*
|
|
||||||
* @return Create and return a dom4j {@code SAXReader} which will append all validation errors
|
public SAXReader createSAXReader(ErrorLogger errorLogger, EntityResolver entityResolver) {
|
||||||
* to the passed error list
|
SAXReader saxReader = new SAXReader();
|
||||||
*/
|
saxReader.setMergeAdjacentText( true );
|
||||||
public SAXReader createSAXReader(ErrorHandler errorHandler, EntityResolver entityResolver) {
|
saxReader.setValidation( true );
|
||||||
SAXReader saxReader = resolveSAXReader();
|
saxReader.setErrorHandler( errorLogger );
|
||||||
saxReader.setEntityResolver( entityResolver );
|
saxReader.setEntityResolver( entityResolver );
|
||||||
saxReader.setErrorHandler( errorHandler );
|
|
||||||
return saxReader;
|
return saxReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SAXReader resolveSAXReader() {
|
|
||||||
if ( saxReader == null ) {
|
|
||||||
saxReader = new SAXReader();
|
|
||||||
saxReader.setMergeAdjacentText( true );
|
|
||||||
saxReader.setValidation( true );
|
|
||||||
}
|
|
||||||
return saxReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return create and return a dom4j DOMReader
|
|
||||||
*/
|
|
||||||
public DOMReader createDOMReader() {
|
|
||||||
if ( domReader == null ) {
|
|
||||||
domReader = new DOMReader();
|
|
||||||
}
|
|
||||||
return domReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Element generateDom4jElement(String elementName) {
|
|
||||||
return getDocumentFactory().createElement( elementName );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DocumentFactory getDocumentFactory() {
|
|
||||||
|
|
||||||
ClassLoader cl = ClassLoaderHelper.getContextClassLoader();
|
|
||||||
DocumentFactory factory;
|
|
||||||
try {
|
|
||||||
Thread.currentThread().setContextClassLoader( XMLHelper.class.getClassLoader() );
|
|
||||||
factory = DocumentFactory.getInstance();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Thread.currentThread().setContextClassLoader( cl );
|
|
||||||
}
|
|
||||||
return factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void dump(Element element) {
|
|
||||||
try {
|
|
||||||
// try to "pretty print" it
|
|
||||||
OutputFormat outFormat = OutputFormat.createPrettyPrint();
|
|
||||||
XMLWriter writer = new XMLWriter( System.out, outFormat );
|
|
||||||
writer.write( element );
|
|
||||||
writer.flush();
|
|
||||||
System.out.println( "" );
|
|
||||||
}
|
|
||||||
catch ( Throwable t ) {
|
|
||||||
// otherwise, just dump it
|
|
||||||
System.out.println( element.asXML() );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
package org.hibernate.mapping;
|
package org.hibernate.mapping;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.PrimitiveType;
|
import org.hibernate.type.PrimitiveType;
|
||||||
|
|
||||||
|
@ -33,10 +34,13 @@ public class Array extends List {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
return ReflectHelper.classForName( elementClassName );
|
return getMetadata().getMetadataBuildingOptions()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class )
|
||||||
|
.classForName( elementClassName );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassLoadingException e) {
|
||||||
throw new MappingException( cnfe );
|
throw new MappingException( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.mapping;
|
package org.hibernate.mapping;
|
||||||
|
|
||||||
import org.hibernate.property.BackrefPropertyAccessor;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.property.PropertyAccessor;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
@ -39,9 +40,14 @@ public class Backref extends Property {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PropertyAccessStrategy propertyAccessStrategy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyAccessor getPropertyAccessor(Class clazz) {
|
public PropertyAccessStrategy getPropertyAccessStrategy(Class clazz) throws MappingException {
|
||||||
return new BackrefPropertyAccessor(collectionRole, entityName);
|
if ( propertyAccessStrategy == null ) {
|
||||||
|
propertyAccessStrategy = new PropertyAccessStrategyBackRefImpl( collectionRole, entityName );
|
||||||
|
}
|
||||||
|
return propertyAccessStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEntityName() {
|
public String getEntityName() {
|
||||||
|
|
|
@ -15,12 +15,13 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.hibernate.FetchMode;
|
import org.hibernate.FetchMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.FilterConfiguration;
|
import org.hibernate.internal.FilterConfiguration;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.CollectionType;
|
import org.hibernate.type.CollectionType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -95,6 +96,11 @@ public abstract class Collection implements Fetchable, Value, Filterable {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceRegistry getServiceRegistry() {
|
||||||
|
return getMetadata().getMetadataBuildingOptions().getServiceRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSet() {
|
public boolean isSet() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +132,10 @@ public abstract class Collection implements Fetchable, Value, Filterable {
|
||||||
public Comparator getComparator() {
|
public Comparator getComparator() {
|
||||||
if ( comparator == null && comparatorClassName != null ) {
|
if ( comparator == null && comparatorClassName != null ) {
|
||||||
try {
|
try {
|
||||||
setComparator( (Comparator) ReflectHelper.classForName( comparatorClassName ).newInstance() );
|
final ClassLoaderService classLoaderService = getMetadata().getMetadataBuildingOptions()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class );
|
||||||
|
setComparator( (Comparator) classLoaderService.classForName( comparatorClassName ).newInstance() );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
|
|
|
@ -16,15 +16,16 @@ import org.hibernate.EntityMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.model.relational.Database;
|
import org.hibernate.boot.model.relational.Database;
|
||||||
import org.hibernate.boot.model.relational.ExportableProducer;
|
import org.hibernate.boot.model.relational.ExportableProducer;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
|
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
import org.hibernate.property.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
import org.hibernate.tuple.component.ComponentMetamodel;
|
import org.hibernate.tuple.component.ComponentMetamodel;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.TypeFactory;
|
import org.hibernate.type.TypeFactory;
|
||||||
|
@ -120,11 +121,14 @@ public class Component extends SimpleValue implements MetaAttributable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getComponentClass() throws MappingException {
|
public Class getComponentClass() throws MappingException {
|
||||||
|
final ClassLoaderService classLoaderService = getMetadata().getMetadataBuildingOptions()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class );
|
||||||
try {
|
try {
|
||||||
return ReflectHelper.classForName(componentClassName);
|
return classLoaderService.classForName( componentClassName );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassLoadingException e) {
|
||||||
throw new MappingException("component class not found: " + componentClassName, cnfe);
|
throw new MappingException("component class not found: " + componentClassName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +167,7 @@ public class Component extends SimpleValue implements MetaAttributable {
|
||||||
@Override
|
@Override
|
||||||
public Type getType() throws MappingException {
|
public Type getType() throws MappingException {
|
||||||
// TODO : temporary initial step towards HHH-1907
|
// TODO : temporary initial step towards HHH-1907
|
||||||
final ComponentMetamodel metamodel = new ComponentMetamodel( this );
|
final ComponentMetamodel metamodel = new ComponentMetamodel( this, getMetadata().getMetadataBuildingOptions() );
|
||||||
final TypeFactory factory = getMetadata().getTypeResolver().getTypeFactory();
|
final TypeFactory factory = getMetadata().getTypeResolver().getTypeFactory();
|
||||||
return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel );
|
return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel );
|
||||||
}
|
}
|
||||||
|
@ -379,8 +383,9 @@ public class Component extends SimpleValue implements MetaAttributable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Setter injector(Property property, Class attributeDeclarer) {
|
private Setter injector(Property property, Class attributeDeclarer) {
|
||||||
return property.getPropertyAccessor( attributeDeclarer )
|
return property.getPropertyAccessStrategy( attributeDeclarer )
|
||||||
.getSetter( attributeDeclarer, property.getName() );
|
.buildPropertyAccess( attributeDeclarer, property.getName() )
|
||||||
|
.getSetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class resolveComponentClass() {
|
private Class resolveComponentClass() {
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.mapping;
|
package org.hibernate.mapping;
|
||||||
|
|
||||||
import org.hibernate.property.IndexPropertyAccessor;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.property.PropertyAccessor;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyIndexBackRefImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
|
@ -39,11 +40,16 @@ public class IndexBackref extends Property {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PropertyAccessStrategy accessStrategy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyAccessor getPropertyAccessor(Class clazz) {
|
public PropertyAccessStrategy getPropertyAccessStrategy(Class clazz) throws MappingException {
|
||||||
return new IndexPropertyAccessor(collectionRole, entityName);
|
if ( accessStrategy == null ) {
|
||||||
|
accessStrategy = new PropertyAccessStrategyIndexBackRefImpl( collectionRole, entityName );
|
||||||
|
}
|
||||||
|
return accessStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEntityName() {
|
public String getEntityName() {
|
||||||
return entityName;
|
return entityName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.mapping;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,12 +16,11 @@ import org.hibernate.engine.spi.Mapping;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class JoinedSubclass extends Subclass implements TableOwner {
|
public class JoinedSubclass extends Subclass implements TableOwner {
|
||||||
|
|
||||||
private Table table;
|
private Table table;
|
||||||
private KeyValue key;
|
private KeyValue key;
|
||||||
|
|
||||||
public JoinedSubclass(PersistentClass superclass) {
|
public JoinedSubclass(PersistentClass superclass, MetadataBuildingContext metadataBuildingContext) {
|
||||||
super(superclass);
|
super( superclass, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table getTable() {
|
public Table getTable() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.FetchMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.EntityType;
|
import org.hibernate.type.EntityType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
@ -34,6 +35,11 @@ public class OneToMany implements Value {
|
||||||
this.referencingTable = ( owner == null ) ? null : owner.getTable();
|
this.referencingTable = ( owner == null ) ? null : owner.getTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceRegistry getServiceRegistry() {
|
||||||
|
return metadata.getMetadataBuildingOptions().getServiceRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
private EntityType getEntityType() {
|
private EntityType getEntityType() {
|
||||||
return metadata.getTypeResolver().getTypeFactory().manyToOne(
|
return metadata.getTypeResolver().getTypeFactory().manyToOne(
|
||||||
getReferencedEntityName(),
|
getReferencedEntityName(),
|
||||||
|
|
|
@ -16,6 +16,8 @@ import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
@ -25,6 +27,7 @@ import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.collections.EmptyIterator;
|
import org.hibernate.internal.util.collections.EmptyIterator;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
import org.hibernate.internal.util.collections.SingletonIterator;
|
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,12 +36,13 @@ import org.hibernate.sql.Alias;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public abstract class PersistentClass implements AttributeContainer, Serializable, Filterable, MetaAttributable {
|
public abstract class PersistentClass implements AttributeContainer, Serializable, Filterable, MetaAttributable {
|
||||||
|
|
||||||
private static final Alias PK_ALIAS = new Alias( 15, "PK" );
|
private static final Alias PK_ALIAS = new Alias( 15, "PK" );
|
||||||
|
|
||||||
public static final String NULL_DISCRIMINATOR_MAPPING = "null";
|
public static final String NULL_DISCRIMINATOR_MAPPING = "null";
|
||||||
public static final String NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
|
public static final String NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
|
||||||
|
|
||||||
|
private final MetadataBuildingContext metadataBuildingContext;
|
||||||
|
|
||||||
private String entityName;
|
private String entityName;
|
||||||
|
|
||||||
private String className;
|
private String className;
|
||||||
|
@ -88,6 +92,14 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
private Component declaredIdentifierMapper;
|
private Component declaredIdentifierMapper;
|
||||||
private OptimisticLockStyle optimisticLockStyle;
|
private OptimisticLockStyle optimisticLockStyle;
|
||||||
|
|
||||||
|
public PersistentClass(MetadataBuildingContext metadataBuildingContext) {
|
||||||
|
this.metadataBuildingContext = metadataBuildingContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceRegistry getServiceRegistry() {
|
||||||
|
return metadataBuildingContext.getBuildingOptions().getServiceRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
public String getClassName() {
|
||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
@ -110,14 +122,15 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
if ( className == null ) {
|
if ( className == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( mappedClass == null ) {
|
if ( mappedClass == null ) {
|
||||||
mappedClass = ReflectHelper.classForName( className );
|
mappedClass = metadataBuildingContext.getClassLoaderAccess().classForName( className );
|
||||||
}
|
}
|
||||||
return mappedClass;
|
return mappedClass;
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassLoadingException e) {
|
||||||
throw new MappingException( "entity class not found: " + className, cnfe );
|
throw new MappingException( "entity class not found: " + className, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +140,12 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if ( proxyInterface == null ) {
|
if ( proxyInterface == null ) {
|
||||||
proxyInterface = ReflectHelper.classForName( proxyInterfaceName );
|
proxyInterface = metadataBuildingContext.getClassLoaderAccess().classForName( proxyInterfaceName );
|
||||||
}
|
}
|
||||||
return proxyInterface;
|
return proxyInterface;
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassLoadingException e) {
|
||||||
throw new MappingException( "proxy class not found: " + proxyInterfaceName, cnfe );
|
throw new MappingException( "proxy class not found: " + proxyInterfaceName, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,18 @@ import java.util.Iterator;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.PropertyNotFoundException;
|
import org.hibernate.PropertyNotFoundException;
|
||||||
import org.hibernate.engine.spi.CascadeStyle;
|
import org.hibernate.engine.spi.CascadeStyle;
|
||||||
import org.hibernate.engine.spi.CascadeStyles;
|
import org.hibernate.engine.spi.CascadeStyles;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.access.spi.Getter;
|
||||||
import org.hibernate.property.PropertyAccessor;
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
import org.hibernate.property.PropertyAccessorFactory;
|
import org.hibernate.property.access.spi.PropertyAccessStrategyResolver;
|
||||||
import org.hibernate.property.Setter;
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.tuple.ValueGeneration;
|
import org.hibernate.tuple.ValueGeneration;
|
||||||
import org.hibernate.type.CompositeType;
|
import org.hibernate.type.CompositeType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
@ -205,7 +207,7 @@ public class Property implements Serializable, MetaAttributable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBasicPropertyAccessor() {
|
public boolean isBasicPropertyAccessor() {
|
||||||
return propertyAccessorName==null || "property".equals(propertyAccessorName);
|
return propertyAccessorName==null || "property".equals( propertyAccessorName );
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.Map getMetaAttributes() {
|
public java.util.Map getMetaAttributes() {
|
||||||
|
@ -303,17 +305,44 @@ public class Property implements Serializable, MetaAttributable {
|
||||||
|
|
||||||
// todo : remove
|
// todo : remove
|
||||||
public Getter getGetter(Class clazz) throws PropertyNotFoundException, MappingException {
|
public Getter getGetter(Class clazz) throws PropertyNotFoundException, MappingException {
|
||||||
return getPropertyAccessor(clazz).getGetter( clazz, name );
|
return getPropertyAccessStrategy( clazz ).buildPropertyAccess( clazz, name ).getGetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo : remove
|
// todo : remove
|
||||||
public Setter getSetter(Class clazz) throws PropertyNotFoundException, MappingException {
|
public Setter getSetter(Class clazz) throws PropertyNotFoundException, MappingException {
|
||||||
return getPropertyAccessor(clazz).getSetter(clazz, name);
|
return getPropertyAccessStrategy( clazz ).buildPropertyAccess( clazz, name ).getSetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo : remove
|
// todo : remove
|
||||||
public PropertyAccessor getPropertyAccessor(Class clazz) throws MappingException {
|
public PropertyAccessStrategy getPropertyAccessStrategy(Class clazz) throws MappingException {
|
||||||
return PropertyAccessorFactory.getPropertyAccessor( clazz, getPropertyAccessorName() );
|
String accessName = getPropertyAccessorName();
|
||||||
|
if ( accessName == null ) {
|
||||||
|
if ( clazz == null || java.util.Map.class.equals( clazz ) ) {
|
||||||
|
accessName = "map";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
accessName = "property";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final EntityMode entityMode = clazz == null || java.util.Map.class.equals( clazz )
|
||||||
|
? EntityMode.MAP
|
||||||
|
: EntityMode.POJO;
|
||||||
|
|
||||||
|
return resolveServiceRegistry().getService( PropertyAccessStrategyResolver.class ).resolvePropertyAccessStrategy(
|
||||||
|
accessName,
|
||||||
|
entityMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ServiceRegistry resolveServiceRegistry() {
|
||||||
|
if ( getPersistentClass() != null ) {
|
||||||
|
return getPersistentClass().getServiceRegistry();
|
||||||
|
}
|
||||||
|
if ( getValue() != null ) {
|
||||||
|
return getValue().getServiceRegistry();
|
||||||
|
}
|
||||||
|
throw new HibernateException( "Could not resolve ServiceRegistry" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNaturalIdentifier() {
|
public boolean isNaturalIdentifier() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
@ -51,6 +52,10 @@ public class RootClass extends PersistentClass implements TableOwner {
|
||||||
private Property declaredVersion;
|
private Property declaredVersion;
|
||||||
private boolean cachingExplicitlyRequested;
|
private boolean cachingExplicitlyRequested;
|
||||||
|
|
||||||
|
public RootClass(MetadataBuildingContext metadataBuildingContext) {
|
||||||
|
super( metadataBuildingContext );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
int nextSubclassId() {
|
int nextSubclassId() {
|
||||||
return ++nextSubclassId;
|
return ++nextSubclassId;
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.FetchMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.common.reflection.XProperty;
|
import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.cfg.AttributeConverterDefinition;
|
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
@ -31,6 +32,7 @@ import org.hibernate.id.factory.IdentifierGeneratorFactory;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
|
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
|
||||||
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
|
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
|
||||||
|
@ -83,6 +85,11 @@ public class SimpleValue implements KeyValue {
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceRegistry getServiceRegistry() {
|
||||||
|
return getMetadata().getMetadataBuildingOptions().getServiceRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCascadeDeleteEnabled() {
|
public boolean isCascadeDeleteEnabled() {
|
||||||
return cascadeDeleteEnabled;
|
return cascadeDeleteEnabled;
|
||||||
|
@ -398,7 +405,7 @@ public class SimpleValue implements KeyValue {
|
||||||
if ( className == null ) {
|
if ( className == null ) {
|
||||||
throw new MappingException( "Attribute types for a dynamic entity must be explicitly specified: " + propertyName );
|
throw new MappingException( "Attribute types for a dynamic entity must be explicitly specified: " + propertyName );
|
||||||
}
|
}
|
||||||
typeName = ReflectHelper.reflectedPropertyClass( className, propertyName ).getName();
|
typeName = ReflectHelper.reflectedPropertyClass( className, propertyName, metadata.getMetadataBuildingOptions().getServiceRegistry().getService( ClassLoaderService.class ) ).getName();
|
||||||
// todo : to fully support isNationalized here we need do the process hinted at above
|
// todo : to fully support isNationalized here we need do the process hinted at above
|
||||||
// essentially, much of the logic from #buildAttributeConverterTypeAdapter wrt resolving
|
// essentially, much of the logic from #buildAttributeConverterTypeAdapter wrt resolving
|
||||||
// a (1) SqlTypeDescriptor, a (2) JavaTypeDescriptor and dynamically building a BasicType
|
// a (1) SqlTypeDescriptor, a (2) JavaTypeDescriptor and dynamically building a BasicType
|
||||||
|
@ -554,10 +561,13 @@ public class SimpleValue implements KeyValue {
|
||||||
? null
|
? null
|
||||||
: xProperty.getAnnotations();
|
: xProperty.getAnnotations();
|
||||||
|
|
||||||
|
final ClassLoaderService classLoaderService = getMetadata().getMetadataBuildingOptions()
|
||||||
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class );
|
||||||
typeParameters.put(
|
typeParameters.put(
|
||||||
DynamicParameterizedType.PARAMETER_TYPE,
|
DynamicParameterizedType.PARAMETER_TYPE,
|
||||||
new ParameterTypeImpl(
|
new ParameterTypeImpl(
|
||||||
ReflectHelper.classForName(
|
classLoaderService.classForName(
|
||||||
typeParameters.getProperty( DynamicParameterizedType.RETURNED_CLASS )
|
typeParameters.getProperty( DynamicParameterizedType.RETURNED_CLASS )
|
||||||
),
|
),
|
||||||
annotations,
|
annotations,
|
||||||
|
@ -569,8 +579,8 @@ public class SimpleValue implements KeyValue {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch ( ClassNotFoundException cnfe ) {
|
catch ( ClassLoadingException e ) {
|
||||||
throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, cnfe );
|
throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.mapping;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
|
|
||||||
|
@ -17,8 +18,8 @@ import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
*/
|
*/
|
||||||
public class SingleTableSubclass extends Subclass {
|
public class SingleTableSubclass extends Subclass {
|
||||||
|
|
||||||
public SingleTableSubclass(PersistentClass superclass) {
|
public SingleTableSubclass(PersistentClass superclass, MetadataBuildingContext metadataBuildingContext) {
|
||||||
super( superclass );
|
super( superclass, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.OptimisticLockStyle;
|
import org.hibernate.engine.OptimisticLockStyle;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
import org.hibernate.internal.util.collections.SingletonIterator;
|
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||||
|
@ -22,12 +23,12 @@ import org.hibernate.internal.util.collections.SingletonIterator;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class Subclass extends PersistentClass {
|
public class Subclass extends PersistentClass {
|
||||||
|
|
||||||
private PersistentClass superclass;
|
private PersistentClass superclass;
|
||||||
private Class classPersisterClass;
|
private Class classPersisterClass;
|
||||||
private final int subclassId;
|
private final int subclassId;
|
||||||
|
|
||||||
public Subclass(PersistentClass superclass) {
|
public Subclass(PersistentClass superclass, MetadataBuildingContext metadataBuildingContext) {
|
||||||
|
super( metadataBuildingContext );
|
||||||
this.superclass = superclass;
|
this.superclass = superclass;
|
||||||
this.subclassId = superclass.nextSubclassId();
|
this.subclassId = superclass.nextSubclassId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.mapping;
|
||||||
|
|
||||||
import org.hibernate.FetchMode;
|
import org.hibernate.FetchMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.spi.MetadataImplementor;
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
@ -18,7 +19,6 @@ import org.hibernate.type.Type;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public abstract class ToOne extends SimpleValue implements Fetchable {
|
public abstract class ToOne extends SimpleValue implements Fetchable {
|
||||||
|
|
||||||
private FetchMode fetchMode;
|
private FetchMode fetchMode;
|
||||||
protected String referencedPropertyName;
|
protected String referencedPropertyName;
|
||||||
private String referencedEntityName;
|
private String referencedEntityName;
|
||||||
|
@ -59,10 +59,12 @@ public abstract class ToOne extends SimpleValue implements Fetchable {
|
||||||
null : referencedEntityName.intern();
|
null : referencedEntityName.intern();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTypeUsingReflection(String className, String propertyName)
|
public void setTypeUsingReflection(String className, String propertyName) throws MappingException {
|
||||||
throws MappingException {
|
if (referencedEntityName == null) {
|
||||||
if (referencedEntityName==null) {
|
final ClassLoaderService cls = getMetadata().getMetadataBuildingOptions()
|
||||||
referencedEntityName = ReflectHelper.reflectedPropertyClass( className, propertyName ).getName();
|
.getServiceRegistry()
|
||||||
|
.getService( ClassLoaderService.class );
|
||||||
|
referencedEntityName = ReflectHelper.reflectedPropertyClass( className, propertyName, cls ).getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.mapping;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,12 +16,11 @@ import org.hibernate.engine.spi.Mapping;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class UnionSubclass extends Subclass implements TableOwner {
|
public class UnionSubclass extends Subclass implements TableOwner {
|
||||||
|
|
||||||
private Table table;
|
private Table table;
|
||||||
private KeyValue key;
|
private KeyValue key;
|
||||||
|
|
||||||
public UnionSubclass(PersistentClass superclass) {
|
public UnionSubclass(PersistentClass superclass, MetadataBuildingContext metadataBuildingContext) {
|
||||||
super(superclass);
|
super( superclass, metadataBuildingContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table getTable() {
|
public Table getTable() {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Iterator;
|
||||||
import org.hibernate.FetchMode;
|
import org.hibernate.FetchMode;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,4 +39,6 @@ public interface Value extends Serializable {
|
||||||
public boolean isValid(Mapping mapping) throws MappingException;
|
public boolean isValid(Mapping mapping) throws MappingException;
|
||||||
public void setTypeUsingReflection(String className, String propertyName) throws MappingException;
|
public void setTypeUsingReflection(String className, String propertyName) throws MappingException;
|
||||||
public Object accept(ValueVisitor visitor);
|
public Object accept(ValueVisitor visitor);
|
||||||
|
|
||||||
|
ServiceRegistry getServiceRegistry();
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper
|
||||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||||
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
import org.hibernate.persister.walking.spi.EntityIdentifierDefinition;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.property.BackrefPropertyAccessor;
|
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
import org.hibernate.sql.Delete;
|
import org.hibernate.sql.Delete;
|
||||||
import org.hibernate.sql.Insert;
|
import org.hibernate.sql.Insert;
|
||||||
|
@ -2645,7 +2645,7 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
for ( int i = 0; i < types.length; i++ ) {
|
for ( int i = 0; i < types.length; i++ ) {
|
||||||
if ( !propertySelectable[i] ) {
|
if ( !propertySelectable[i] ) {
|
||||||
values[i] = BackrefPropertyAccessor.UNKNOWN;
|
values[i] = PropertyAccessStrategyBackRefImpl.UNKNOWN;
|
||||||
}
|
}
|
||||||
else if ( allProperties || !laziness[i] ) {
|
else if ( allProperties || !laziness[i] ) {
|
||||||
//decide which ResultSet to get the property value from:
|
//decide which ResultSet to get the property value from:
|
||||||
|
|
|
@ -1,358 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
|
|
||||||
import java.beans.Introspector;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.PropertyAccessException;
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.PropertySetterAccessException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
import org.hibernate.internal.CoreLogging;
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accesses property values via a get/set pair, which may be nonpublic.
|
|
||||||
* The default (and recommended strategy).
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class BasicPropertyAccessor implements PropertyAccessor {
|
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BasicPropertyAccessor.class );
|
|
||||||
|
|
||||||
public static final class BasicSetter implements Setter {
|
|
||||||
private Class clazz;
|
|
||||||
private final transient Method method;
|
|
||||||
private final String propertyName;
|
|
||||||
|
|
||||||
private BasicSetter(Class clazz, Method method, String propertyName) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.method = method;
|
|
||||||
this.propertyName = propertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory)
|
|
||||||
throws HibernateException {
|
|
||||||
try {
|
|
||||||
method.invoke( target, value );
|
|
||||||
}
|
|
||||||
catch (NullPointerException npe) {
|
|
||||||
if ( value == null && method.getParameterTypes()[0].isPrimitive() ) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
npe,
|
|
||||||
"Null value was assigned to a property of primitive type",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
npe,
|
|
||||||
"NullPointerException occurred while calling",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException ite) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
ite,
|
|
||||||
"Exception occurred inside",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException iae) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"IllegalAccessException occurred while calling",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
//cannot occur
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException iae) {
|
|
||||||
if ( value == null && method.getParameterTypes()[0].isPrimitive() ) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"Null value was assigned to a property of primitive type",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final Class expectedType = method.getParameterTypes()[0];
|
|
||||||
LOG.illegalPropertySetterArgument( clazz.getName(), propertyName );
|
|
||||||
LOG.expectedType( expectedType.getName(), value == null ? null : value.getClass().getName() );
|
|
||||||
throw new PropertySetterAccessException(
|
|
||||||
iae,
|
|
||||||
clazz,
|
|
||||||
propertyName,
|
|
||||||
expectedType,
|
|
||||||
target,
|
|
||||||
value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return method.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
Object readResolve() {
|
|
||||||
return createSetter( clazz, propertyName );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class BasicGetter implements Getter {
|
|
||||||
private Class clazz;
|
|
||||||
private final transient Method method;
|
|
||||||
private final String propertyName;
|
|
||||||
|
|
||||||
private BasicGetter(Class clazz, Method method, String propertyName) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.method = method;
|
|
||||||
this.propertyName = propertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) throws HibernateException {
|
|
||||||
try {
|
|
||||||
return method.invoke( target, (Object[]) null );
|
|
||||||
}
|
|
||||||
catch (InvocationTargetException ite) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
ite,
|
|
||||||
"Exception occurred inside",
|
|
||||||
false,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException iae) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"IllegalAccessException occurred while calling",
|
|
||||||
false,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
//cannot occur
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException iae) {
|
|
||||||
LOG.illegalPropertyGetterArgument( clazz.getName(), propertyName );
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
iae,
|
|
||||||
"IllegalArgumentException occurred calling",
|
|
||||||
false,
|
|
||||||
clazz,
|
|
||||||
propertyName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
|
|
||||||
return get( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return method.getReturnType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return method.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
Object readResolve() {
|
|
||||||
return createGetter( clazz, propertyName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return createSetter( theClass, propertyName );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Setter createSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
BasicSetter result = getSetterOrNull( theClass, propertyName );
|
|
||||||
if ( result == null ) {
|
|
||||||
throw new PropertyNotFoundException(
|
|
||||||
"Could not find a setter for property " +
|
|
||||||
propertyName +
|
|
||||||
" in class " +
|
|
||||||
theClass.getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
|
|
||||||
if ( theClass == Object.class || theClass == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Method method = setterMethod( theClass, propertyName );
|
|
||||||
|
|
||||||
if ( method != null ) {
|
|
||||||
method.setAccessible( true );
|
|
||||||
return new BasicSetter( theClass, method, propertyName );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
|
|
||||||
if ( setter == null ) {
|
|
||||||
Class[] interfaces = theClass.getInterfaces();
|
|
||||||
for ( int i = 0; setter == null && i < interfaces.length; i++ ) {
|
|
||||||
setter = getSetterOrNull( interfaces[i], propertyName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return setter;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method setterMethod(Class theClass, String propertyName) {
|
|
||||||
BasicGetter getter = getGetterOrNull( theClass, propertyName );
|
|
||||||
Class returnType = ( getter == null ) ? null : getter.getReturnType();
|
|
||||||
|
|
||||||
Method[] methods = theClass.getDeclaredMethods();
|
|
||||||
Method potentialSetter = null;
|
|
||||||
for ( Method method : methods ) {
|
|
||||||
final String methodName = method.getName();
|
|
||||||
if ( method.getParameterTypes().length == 1 && methodName.startsWith( "set" ) ) {
|
|
||||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
|
|
||||||
String testOldMethod = methodName.substring( 3 );
|
|
||||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
|
||||||
potentialSetter = method;
|
|
||||||
if ( returnType == null || method.getParameterTypes()[0].equals( returnType ) ) {
|
|
||||||
return potentialSetter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return potentialSetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return createGetter( theClass, propertyName );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Getter createGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
BasicGetter result = getGetterOrNull( theClass, propertyName );
|
|
||||||
if ( result == null ) {
|
|
||||||
throw new PropertyNotFoundException(
|
|
||||||
"Could not find a getter for " +
|
|
||||||
propertyName +
|
|
||||||
" in class " +
|
|
||||||
theClass.getName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BasicGetter getGetterOrNull(Class theClass, String propertyName) {
|
|
||||||
if ( theClass == Object.class || theClass == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Method method = getterMethod( theClass, propertyName );
|
|
||||||
|
|
||||||
if ( method != null ) {
|
|
||||||
method.setAccessible( true );
|
|
||||||
return new BasicGetter( theClass, method, propertyName );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName );
|
|
||||||
if ( getter == null ) {
|
|
||||||
Class[] interfaces = theClass.getInterfaces();
|
|
||||||
for ( int i = 0; getter == null && i < interfaces.length; i++ ) {
|
|
||||||
getter = getGetterOrNull( interfaces[i], propertyName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Method getterMethod(Class theClass, String propertyName) {
|
|
||||||
Method[] methods = theClass.getDeclaredMethods();
|
|
||||||
for ( Method method : methods ) {
|
|
||||||
// if the method has parameters, skip it
|
|
||||||
if ( method.getParameterTypes().length != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// if the method is a "bridge", skip it
|
|
||||||
if ( method.isBridge() ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String methodName = method.getName();
|
|
||||||
|
|
||||||
// try "get"
|
|
||||||
if ( methodName.startsWith( "get" ) ) {
|
|
||||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 3 ) );
|
|
||||||
String testOldMethod = methodName.substring( 3 );
|
|
||||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not "get", then try "is"
|
|
||||||
if ( methodName.startsWith( "is" ) ) {
|
|
||||||
String testStdMethod = Introspector.decapitalize( methodName.substring( 2 ) );
|
|
||||||
String testOldMethod = methodName.substring( 2 );
|
|
||||||
if ( testStdMethod.equals( propertyName ) || testOldMethod.equals( propertyName ) ) {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author max
|
|
||||||
*/
|
|
||||||
public class ChainedPropertyAccessor implements PropertyAccessor {
|
|
||||||
|
|
||||||
final PropertyAccessor[] chain;
|
|
||||||
|
|
||||||
public ChainedPropertyAccessor(PropertyAccessor[] chain) {
|
|
||||||
this.chain = chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Getter getGetter(Class theClass, String propertyName)
|
|
||||||
throws PropertyNotFoundException {
|
|
||||||
Getter result = null;
|
|
||||||
for ( PropertyAccessor candidate : chain ) {
|
|
||||||
try {
|
|
||||||
result = candidate.getGetter( theClass, propertyName );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (PropertyNotFoundException pnfe) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new PropertyNotFoundException( "Could not find getter for " + propertyName + " on " + theClass );
|
|
||||||
}
|
|
||||||
|
|
||||||
public Setter getSetter(Class theClass, String propertyName)
|
|
||||||
throws PropertyNotFoundException {
|
|
||||||
Setter result = null;
|
|
||||||
for ( PropertyAccessor candidate : chain ) {
|
|
||||||
try {
|
|
||||||
result = candidate.getSetter( theClass, propertyName );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (PropertyNotFoundException pnfe) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new PropertyNotFoundException( "Could not find setter for " + propertyName + " on " + theClass );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.PropertyAccessException;
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accesses fields directly.
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class DirectPropertyAccessor implements PropertyAccessor {
|
|
||||||
|
|
||||||
public static final class DirectGetter implements Getter {
|
|
||||||
private final transient Field field;
|
|
||||||
private final Class clazz;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
DirectGetter(Field field, Class clazz, String name) {
|
|
||||||
this.field = field;
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) throws HibernateException {
|
|
||||||
try {
|
|
||||||
return field.get(target);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new PropertyAccessException(e, "could not get a field value by reflection", false, clazz, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
|
|
||||||
return get( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return field.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
Object readResolve() {
|
|
||||||
return new DirectGetter( getField(clazz, name), clazz, name );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DirectGetter(" + clazz.getName() + '.' + name + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class DirectSetter implements Setter {
|
|
||||||
private final transient Field field;
|
|
||||||
private final Class clazz;
|
|
||||||
private final String name;
|
|
||||||
DirectSetter(Field field, Class clazz, String name) {
|
|
||||||
this.field = field;
|
|
||||||
this.clazz = clazz;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {
|
|
||||||
try {
|
|
||||||
field.set(target, value);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
if(value == null && field.getType().isPrimitive()) {
|
|
||||||
throw new PropertyAccessException(
|
|
||||||
e,
|
|
||||||
"Null value was assigned to a property of primitive type",
|
|
||||||
true,
|
|
||||||
clazz,
|
|
||||||
name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new PropertyAccessException(e, "could not set a field value by reflection", true, clazz, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DirectSetter(" + clazz.getName() + '.' + name + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
Object readResolve() {
|
|
||||||
return new DirectSetter( getField(clazz, name), clazz, name );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Field getField(Class clazz, String name) throws PropertyNotFoundException {
|
|
||||||
if ( clazz==null || clazz==Object.class ) {
|
|
||||||
throw new PropertyNotFoundException("field not found: " + name);
|
|
||||||
}
|
|
||||||
Field field;
|
|
||||||
try {
|
|
||||||
field = clazz.getDeclaredField(name);
|
|
||||||
}
|
|
||||||
catch (NoSuchFieldException nsfe) {
|
|
||||||
field = getField( clazz, clazz.getSuperclass(), name );
|
|
||||||
}
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Field getField(Class root, Class clazz, String name) throws PropertyNotFoundException {
|
|
||||||
if ( clazz==null || clazz==Object.class ) {
|
|
||||||
throw new PropertyNotFoundException("field [" + name + "] not found on " + root.getName());
|
|
||||||
}
|
|
||||||
Field field;
|
|
||||||
try {
|
|
||||||
field = clazz.getDeclaredField(name);
|
|
||||||
}
|
|
||||||
catch (NoSuchFieldException nsfe) {
|
|
||||||
field = getField( root, clazz.getSuperclass(), name );
|
|
||||||
}
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return new DirectGetter( getField(theClass, propertyName), theClass, propertyName );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return new DirectSetter( getField(theClass, propertyName), theClass, propertyName );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class EmbeddedPropertyAccessor implements PropertyAccessor {
|
|
||||||
|
|
||||||
public static final class EmbeddedGetter implements Getter {
|
|
||||||
private final Class clazz;
|
|
||||||
|
|
||||||
EmbeddedGetter(Class clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) throws HibernateException {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
|
|
||||||
return get( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "EmbeddedGetter(" + clazz.getName() + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class EmbeddedSetter implements Setter {
|
|
||||||
private final Class clazz;
|
|
||||||
|
|
||||||
EmbeddedSetter(Class clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "EmbeddedSetter(" + clazz.getName() + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return new EmbeddedGetter(theClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
|
|
||||||
return new EmbeddedSetter(theClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a "back-reference" to the index of a collection.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class IndexPropertyAccessor implements PropertyAccessor {
|
|
||||||
private final String propertyName;
|
|
||||||
private final String entityName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 );
|
|
||||||
this.entityName = entityName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Setter getSetter(Class theClass, String propertyName) {
|
|
||||||
return new IndexSetter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class theClass, String propertyName) {
|
|
||||||
return new IndexGetter();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Setter implementation for index backrefs.
|
|
||||||
*/
|
|
||||||
public static final class IndexSetter implements Setter {
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
|
||||||
// do nothing...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Getter implementation for index backrefs.
|
|
||||||
*/
|
|
||||||
public class IndexGetter implements Getter {
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException {
|
|
||||||
if ( session == null ) {
|
|
||||||
return BackrefPropertyAccessor.UNKNOWN;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return session.getPersistenceContext().getIndexInOwner( entityName, propertyName, target, mergeMap );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) {
|
|
||||||
return BackrefPropertyAccessor.UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return Object.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Gavin King
|
|
||||||
*/
|
|
||||||
public class MapAccessor implements PropertyAccessor {
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class theClass, String propertyName)
|
|
||||||
throws PropertyNotFoundException {
|
|
||||||
return new MapGetter(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory)
|
|
||||||
throws HibernateException {
|
|
||||||
( (Map) target ).put( name, value );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class MapGetter implements Getter {
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
MapGetter(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) throws HibernateException {
|
|
||||||
return ( (Map) target ).get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
|
|
||||||
return get( target );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return Object.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
import java.lang.reflect.Member;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.PropertyNotFoundException;
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to declare properties not represented at the pojo level
|
|
||||||
*
|
|
||||||
* @author Michael Bartmann
|
|
||||||
*/
|
|
||||||
public class NoopAccessor implements PropertyAccessor {
|
|
||||||
@Override
|
|
||||||
public Getter getGetter(Class arg0, String arg1) throws PropertyNotFoundException {
|
|
||||||
return new NoopGetter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Setter getSetter(Class arg0, String arg1) throws PropertyNotFoundException {
|
|
||||||
return new NoopSetter();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Getter which will always return null. It should not be called anyway.
|
|
||||||
*/
|
|
||||||
private static class NoopGetter implements Getter {
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* <p/>
|
|
||||||
* Here we always return <tt>null</tt>
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object get(Object target) throws HibernateException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getForInsert(Object target, Map map, SessionImplementor arg1)
|
|
||||||
throws HibernateException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class getReturnType() {
|
|
||||||
return Object.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Member getMember() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Setter which will just do nothing.
|
|
||||||
*/
|
|
||||||
private static class NoopSetter implements Setter {
|
|
||||||
@Override
|
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor arg2) {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
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;
|
|
||||||
}
|
|
|
@ -1,144 +0,0 @@
|
||||||
/*
|
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
|
||||||
*
|
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
|
||||||
*/
|
|
||||||
package org.hibernate.property;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
|
||||||
import org.hibernate.MappingException;
|
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.mapping.Property;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A factory for building/retrieving PropertyAccessor instances.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public final class PropertyAccessorFactory {
|
|
||||||
private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
|
|
||||||
private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
|
|
||||||
private static final PropertyAccessor MAP_ACCESSOR = new MapAccessor();
|
|
||||||
private static final PropertyAccessor NOOP_ACCESSOR = new NoopAccessor();
|
|
||||||
private static final PropertyAccessor EMBEDDED_PROPERTY_ACCESSOR = new EmbeddedPropertyAccessor();
|
|
||||||
|
|
||||||
//TODO: ideally we need the construction of PropertyAccessor to take the following:
|
|
||||||
// 1) EntityMode
|
|
||||||
// 2) EntityMode-specific data (i.e., the classname for pojo entities)
|
|
||||||
// 3) Property-specific data based on the EntityMode (i.e., property-name or dom4j-node-name)
|
|
||||||
// The easiest way, with the introduction of the new runtime-metamodel classes, would be the
|
|
||||||
// the following predicates:
|
|
||||||
// 1) PropertyAccessorFactory.getPropertyAccessor() takes references to both a
|
|
||||||
// org.hibernate.metadata.EntityModeMetadata and org.hibernate.metadata.Property
|
|
||||||
// 2) What is now termed a "PropertyAccessor" stores any values needed from those two
|
|
||||||
// pieces of information
|
|
||||||
// 3) Code can then simply call PropertyAccess.getGetter() with no parameters; likewise with
|
|
||||||
// PropertyAccessor.getSetter()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a PropertyAccessor instance based on the given property definition and
|
|
||||||
* entity mode.
|
|
||||||
*
|
|
||||||
* @param property The property for which to retrieve an accessor.
|
|
||||||
* @param mode The mode for the resulting entity.
|
|
||||||
*
|
|
||||||
* @return An appropriate accessor.
|
|
||||||
*
|
|
||||||
* @throws MappingException
|
|
||||||
*/
|
|
||||||
public static PropertyAccessor getPropertyAccessor(Property property, EntityMode mode) throws MappingException {
|
|
||||||
//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
|
|
||||||
if ( null == mode || EntityMode.POJO.equals( mode ) ) {
|
|
||||||
return getPojoPropertyAccessor( property.getPropertyAccessorName() );
|
|
||||||
}
|
|
||||||
else if ( EntityMode.MAP.equals( mode ) ) {
|
|
||||||
return getDynamicMapPropertyAccessor();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new MappingException( "Unknown entity mode [" + mode + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retreives a PropertyAccessor specific for a PojoRepresentation with the given access strategy.
|
|
||||||
*
|
|
||||||
* @param pojoAccessorStrategy The access strategy.
|
|
||||||
*
|
|
||||||
* @return An appropriate accessor.
|
|
||||||
*/
|
|
||||||
private static PropertyAccessor getPojoPropertyAccessor(String pojoAccessorStrategy) {
|
|
||||||
if ( StringHelper.isEmpty( pojoAccessorStrategy ) || "property".equals( pojoAccessorStrategy ) ) {
|
|
||||||
return BASIC_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
else if ( "field".equals( pojoAccessorStrategy ) ) {
|
|
||||||
return DIRECT_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
else if ( "embedded".equals( pojoAccessorStrategy ) ) {
|
|
||||||
return EMBEDDED_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
else if ( "noop".equals( pojoAccessorStrategy ) ) {
|
|
||||||
return NOOP_ACCESSOR;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return resolveCustomAccessor( pojoAccessorStrategy );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PropertyAccessor getDynamicMapPropertyAccessor() throws MappingException {
|
|
||||||
return MAP_ACCESSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertyAccessor resolveCustomAccessor(String accessorName) {
|
|
||||||
Class accessorClass;
|
|
||||||
try {
|
|
||||||
accessorClass = ReflectHelper.classForName( accessorName );
|
|
||||||
}
|
|
||||||
catch (ClassNotFoundException cnfe) {
|
|
||||||
throw new MappingException( "could not find PropertyAccessor class: " + accessorName, cnfe );
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return (PropertyAccessor) accessorClass.newInstance();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new MappingException( "could not instantiate PropertyAccessor class: " + accessorName, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PropertyAccessorFactory() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo : this eventually needs to be removed
|
|
||||||
public static PropertyAccessor getPropertyAccessor(Class optionalClass, String type) throws MappingException {
|
|
||||||
if ( type == null ) {
|
|
||||||
type = optionalClass == null || optionalClass == Map.class ? "map" : "property";
|
|
||||||
}
|
|
||||||
return getPropertyAccessor( type );
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo : this eventually needs to be removed
|
|
||||||
public static PropertyAccessor getPropertyAccessor(String type) throws MappingException {
|
|
||||||
if ( type == null || "property".equals( type ) ) {
|
|
||||||
return BASIC_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
if ( "field".equals( type ) ) {
|
|
||||||
return DIRECT_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
if ( "map".equals( type ) ) {
|
|
||||||
return MAP_ACCESSOR;
|
|
||||||
}
|
|
||||||
if ( "embedded".equals( type ) ) {
|
|
||||||
return EMBEDDED_PROPERTY_ACCESSOR;
|
|
||||||
}
|
|
||||||
if ( "noop".equals( type ) ) {
|
|
||||||
return NOOP_ACCESSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolveCustomAccessor( type );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessSerializationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract serialization replacement for field based Getter and Setter impls.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public abstract class AbstractFieldSerialForm implements Serializable {
|
||||||
|
private final Class declaringClass;
|
||||||
|
private final String fieldName;
|
||||||
|
|
||||||
|
protected AbstractFieldSerialForm(Field field) {
|
||||||
|
this( field.getDeclaringClass(), field.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractFieldSerialForm(Class declaringClass, String fieldName) {
|
||||||
|
this.declaringClass = declaringClass;
|
||||||
|
this.fieldName = fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Field resolveField() {
|
||||||
|
try {
|
||||||
|
return declaringClass.getDeclaredField( fieldName );
|
||||||
|
}
|
||||||
|
catch (NoSuchFieldException e) {
|
||||||
|
throw new PropertyAccessSerializationException(
|
||||||
|
"Unable to resolve field on deserialization : " + declaringClass.getName() + "#" + fieldName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.GetterMethodImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
import org.hibernate.property.access.spi.SetterMethodImpl;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropertyAccessor for accessing the wrapped property via get/set pair, which may be nonpublic.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*
|
||||||
|
* @see PropertyAccessStrategyBasicImpl
|
||||||
|
*/
|
||||||
|
public class PropertyAccessBasicImpl implements PropertyAccess {
|
||||||
|
private static final Logger log = Logger.getLogger( PropertyAccessBasicImpl.class );
|
||||||
|
|
||||||
|
private final PropertyAccessStrategyBasicImpl strategy;
|
||||||
|
private final GetterMethodImpl getter;
|
||||||
|
private final SetterMethodImpl setter;
|
||||||
|
|
||||||
|
public PropertyAccessBasicImpl(
|
||||||
|
PropertyAccessStrategyBasicImpl strategy,
|
||||||
|
Class containerJavaType,
|
||||||
|
final String propertyName) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
|
||||||
|
final Method getterMethod = ReflectHelper.findGetterMethod( containerJavaType, propertyName );
|
||||||
|
this.getter = new GetterMethodImpl( containerJavaType, propertyName, getterMethod );
|
||||||
|
|
||||||
|
final Method setterMethod = ReflectHelper.findSetterMethod( containerJavaType, propertyName, getterMethod.getReturnType() );
|
||||||
|
this.setter = new SetterMethodImpl( containerJavaType, propertyName, setterMethod );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Getter getGetter() {
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Member;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropertyAccess for handling non-aggregated composites.
|
||||||
|
* <p/>
|
||||||
|
* IMPL NOTE : We actually use a singleton for the Setter; we cannot for the getter mainly
|
||||||
|
* because we need to differentiate {@link Getter#getReturnType()}. Ultimately I'd prefer to
|
||||||
|
* model that "common information" on PropertyAccess itself.
|
||||||
|
*
|
||||||
|
* @author Gavin King
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PropertyAccessEmbeddedImpl implements PropertyAccess {
|
||||||
|
private final PropertyAccessStrategyEmbeddedImpl strategy;
|
||||||
|
private final GetterImpl getter;
|
||||||
|
|
||||||
|
@SuppressWarnings("UnusedParameters")
|
||||||
|
public PropertyAccessEmbeddedImpl(
|
||||||
|
PropertyAccessStrategyEmbeddedImpl strategy,
|
||||||
|
Class containerType,
|
||||||
|
String propertyName) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
this.getter = new GetterImpl( containerType );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Getter getGetter() {
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return SetterImpl.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GetterImpl implements Getter {
|
||||||
|
private final Class containerType;
|
||||||
|
|
||||||
|
public GetterImpl(Class containerType) {
|
||||||
|
this.containerType = containerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Object owner) {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getReturnType() {
|
||||||
|
return containerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Member getMember() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethodName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method getMethod() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SetterImpl implements Setter {
|
||||||
|
/**
|
||||||
|
* Singleton access - we can actually use a singleton for the setter
|
||||||
|
*/
|
||||||
|
public static final SetterImpl INSTANCE = new SetterImpl();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethodName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method getMethod() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.GetterFieldImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
import org.hibernate.property.access.spi.SetterFieldImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
public class PropertyAccessFieldImpl implements PropertyAccess {
|
||||||
|
private final PropertyAccessStrategyFieldImpl strategy;
|
||||||
|
private final GetterFieldImpl getter;
|
||||||
|
private final SetterFieldImpl setter;
|
||||||
|
|
||||||
|
public PropertyAccessFieldImpl(
|
||||||
|
PropertyAccessStrategyFieldImpl strategy,
|
||||||
|
Class containerJavaType,
|
||||||
|
final String propertyName) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
|
||||||
|
final Field field = ReflectHelper.findField( containerJavaType, propertyName );
|
||||||
|
this.getter = new GetterFieldImpl( containerJavaType, propertyName, field );
|
||||||
|
this.setter = new SetterFieldImpl( containerJavaType, propertyName, field );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Getter getGetter() {
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Member;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PropertyAccess implementation that deal with an underlying Map as the container using
|
||||||
|
* {@link Map#get} and {@link Map#put}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
public class PropertyAccessMapImpl implements PropertyAccess {
|
||||||
|
private final Getter getter;
|
||||||
|
private final Setter setter;
|
||||||
|
private final PropertyAccessStrategyMapImpl strategy;
|
||||||
|
|
||||||
|
public PropertyAccessMapImpl(PropertyAccessStrategyMapImpl strategy, final String propertyName) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
this.getter = new GetterImpl( propertyName );
|
||||||
|
this.setter = new SetterImpl( propertyName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Getter getGetter() {
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GetterImpl implements Getter {
|
||||||
|
private final String propertyName;
|
||||||
|
|
||||||
|
public GetterImpl(String propertyName) {
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Object owner) {
|
||||||
|
return ( (Map) owner ).get( propertyName );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) {
|
||||||
|
return get( owner );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getReturnType() {
|
||||||
|
// we just don't know...
|
||||||
|
return Object.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Member getMember() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethodName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method getMethod() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SetterImpl implements Setter {
|
||||||
|
private final String propertyName;
|
||||||
|
|
||||||
|
public SetterImpl(String propertyName) {
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
||||||
|
( (Map) target ).put( propertyName, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethodName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method getMethod() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.hibernate.PropertyNotFoundException;
|
||||||
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.GetterFieldImpl;
|
||||||
|
import org.hibernate.property.access.spi.GetterMethodImpl;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessBuildingException;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
import org.hibernate.property.access.spi.SetterFieldImpl;
|
||||||
|
import org.hibernate.property.access.spi.SetterMethodImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A PropertyAccess based on mix of getter/setter method and/or field.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class PropertyAccessMixedImpl implements PropertyAccess {
|
||||||
|
private final PropertyAccessStrategyMixedImpl strategy;
|
||||||
|
|
||||||
|
private final Getter getter;
|
||||||
|
private final Setter setter;
|
||||||
|
|
||||||
|
public PropertyAccessMixedImpl(
|
||||||
|
PropertyAccessStrategyMixedImpl strategy,
|
||||||
|
Class containerJavaType,
|
||||||
|
String propertyName) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
|
||||||
|
final Field field = fieldOrNull( containerJavaType, propertyName );
|
||||||
|
final Method getterMethod = getterMethodOrNull( containerJavaType, propertyName );
|
||||||
|
|
||||||
|
final Class propertyJavaType;
|
||||||
|
|
||||||
|
// need one of field or getterMethod to be non-null
|
||||||
|
if ( field == null && getterMethod == null ) {
|
||||||
|
throw new PropertyAccessBuildingException(
|
||||||
|
"Could not locate field nor getter method for property named [" + containerJavaType.getName() +
|
||||||
|
"#" + propertyName + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( field != null ) {
|
||||||
|
propertyJavaType = field.getType();
|
||||||
|
this.getter = new GetterFieldImpl( containerJavaType, propertyName, field );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
propertyJavaType = getterMethod.getReturnType();
|
||||||
|
this.getter = new GetterMethodImpl( containerJavaType, propertyName, getterMethod );
|
||||||
|
}
|
||||||
|
|
||||||
|
final Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, propertyJavaType );
|
||||||
|
|
||||||
|
// need one of field or setterMethod to be non-null
|
||||||
|
if ( field == null && setterMethod == null ) {
|
||||||
|
throw new PropertyAccessBuildingException(
|
||||||
|
"Could not locate field nor setter method for property named [" + containerJavaType.getName() +
|
||||||
|
"#" + propertyName + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( field != null ) {
|
||||||
|
this.setter = new SetterFieldImpl( containerJavaType, propertyName, field );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.setter = new SetterMethodImpl( containerJavaType, propertyName, setterMethod );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Field fieldOrNull(Class containerJavaType, String propertyName) {
|
||||||
|
try {
|
||||||
|
return ReflectHelper.findField( containerJavaType, propertyName );
|
||||||
|
}
|
||||||
|
catch (PropertyNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method getterMethodOrNull(Class containerJavaType, String propertyName) {
|
||||||
|
try {
|
||||||
|
return ReflectHelper.findGetterMethod( containerJavaType, propertyName );
|
||||||
|
}
|
||||||
|
catch (PropertyNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method setterMethodOrNull(Class containerJavaType, String propertyName, Class propertyJavaType) {
|
||||||
|
try {
|
||||||
|
return ReflectHelper.findSetterMethod( containerJavaType, propertyName, propertyJavaType );
|
||||||
|
}
|
||||||
|
catch (PropertyNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Getter getGetter() {
|
||||||
|
return getter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,8 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.property;
|
package org.hibernate.property.access.internal;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
@ -12,27 +13,16 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SessionImplementor;
|
import org.hibernate.engine.spi.SessionImplementor;
|
||||||
|
import org.hibernate.property.access.spi.Getter;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccess;
|
||||||
|
import org.hibernate.property.access.spi.PropertyAccessStrategy;
|
||||||
|
import org.hibernate.property.access.spi.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a "back-reference" to the id of a collection owner. A "back-reference" is pertinent in mapping scenarios
|
|
||||||
* where we have a uni-directional one-to-many association in which only the many side is mapped. In this case it is
|
|
||||||
* the collection itself which is responsible for the FK value.
|
|
||||||
* <p/>
|
|
||||||
* In this scenario, the one side has no inherent knowledge of its "owner". So we introduce a synthetic property into
|
|
||||||
* the one side to represent the association; a so-called back-reference.
|
|
||||||
*
|
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BackrefPropertyAccessor implements PropertyAccessor {
|
public class PropertyAccessStrategyBackRefImpl implements PropertyAccessStrategy {
|
||||||
|
|
||||||
private final String propertyName;
|
|
||||||
private final String entityName;
|
|
||||||
|
|
||||||
// cache these since they are stateless
|
|
||||||
private final BackrefSetter setter; // this one could even be static...
|
|
||||||
private final BackrefGetter getter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A placeholder for a property value, indicating that
|
* A placeholder for a property value, indicating that
|
||||||
* we don't know the value of the back reference
|
* we don't know the value of the back reference
|
||||||
|
@ -48,81 +38,100 @@ public class BackrefPropertyAccessor implements PropertyAccessor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
private final String entityName;
|
||||||
* Constructs a new instance of BackrefPropertyAccessor.
|
private final String propertyName;
|
||||||
*
|
|
||||||
* @param collectionRole The collection role which this back ref references.
|
public PropertyAccessStrategyBackRefImpl(String collectionRole, String entityName) {
|
||||||
* @param entityName The owner's entity name.
|
|
||||||
*/
|
|
||||||
public BackrefPropertyAccessor(String collectionRole, String entityName) {
|
|
||||||
this.propertyName = collectionRole.substring( entityName.length() + 1 );
|
|
||||||
this.entityName = entityName;
|
this.entityName = entityName;
|
||||||
|
this.propertyName = collectionRole.substring( entityName.length() + 1 );
|
||||||
this.setter = new BackrefSetter();
|
|
||||||
this.getter = new BackrefGetter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Setter getSetter(Class theClass, String propertyName) {
|
public PropertyAccess buildPropertyAccess(Class containerJavaType, String propertyName) {
|
||||||
return setter;
|
return new PropertyAccessBackRefImpl( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static class PropertyAccessBackRefImpl implements PropertyAccess {
|
||||||
public Getter getGetter(Class theClass, String propertyName) {
|
private PropertyAccessStrategyBackRefImpl strategy;
|
||||||
return getter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private final GetterImpl getter;
|
||||||
|
|
||||||
/**
|
public PropertyAccessBackRefImpl(PropertyAccessStrategyBackRefImpl strategy) {
|
||||||
* Internal implementation of a property setter specific to these back-ref properties.
|
this.strategy = strategy;
|
||||||
*/
|
this.getter = new GetterImpl( strategy.entityName, strategy.propertyName );
|
||||||
public static final class BackrefSetter implements Setter {
|
|
||||||
@Override
|
|
||||||
public Method getMethod() {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMethodName() {
|
public PropertyAccessStrategy getPropertyAccessStrategy() {
|
||||||
return null;
|
return strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
public Getter getGetter() {
|
||||||
// this page intentionally left blank :)
|
return getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Setter getSetter() {
|
||||||
|
return SetterImpl.INSTANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class GetterImpl implements Getter {
|
||||||
|
private final String entityName;
|
||||||
|
private final String propertyName;
|
||||||
|
|
||||||
|
public GetterImpl(String entityName, String propertyName) {
|
||||||
|
this.entityName = entityName;
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal implementation of a property getter specific to these back-ref properties.
|
|
||||||
*/
|
|
||||||
public class BackrefGetter implements Getter {
|
|
||||||
@Override
|
@Override
|
||||||
public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
|
public Object get(Object owner) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) {
|
||||||
if ( session == null ) {
|
if ( session == null ) {
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return session.getPersistenceContext().getOwnerId( entityName, propertyName, target, mergeMap );
|
return session.getPersistenceContext().getOwnerId( entityName, propertyName, owner, mergeMap );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getReturnType() {
|
||||||
|
return Object.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Member getMember() {
|
public Member getMember() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object get(Object target) {
|
public String getMethodName() {
|
||||||
return UNKNOWN;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Method getMethod() {
|
public Method getMethod() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SetterImpl implements Setter {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final SetterImpl INSTANCE = new SetterImpl();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object target, Object value, SessionFactoryImplementor factory) {
|
||||||
|
// this page intentionally left blank :)
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMethodName() {
|
public String getMethodName() {
|
||||||
|
@ -130,9 +139,8 @@ public class BackrefPropertyAccessor implements PropertyAccessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class getReturnType() {
|
public Method getMethod() {
|
||||||
return Object.class;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue