HHH-6109 Starting work for annotation binding against the new metamodel. Enabling JAXB for parsing of orm.xml
This commit is contained in:
parent
72a2862ea9
commit
42502e696b
10
build.gradle
10
build.gradle
|
@ -46,6 +46,7 @@ libraries = [
|
||||||
// Annotations
|
// Annotations
|
||||||
commons_annotations:
|
commons_annotations:
|
||||||
'org.hibernate:hibernate-commons-annotations:3.2.0.Final',
|
'org.hibernate:hibernate-commons-annotations:3.2.0.Final',
|
||||||
|
jandex: 'org.jboss:jandex:1.0.0.Beta6',
|
||||||
|
|
||||||
// Jakarta commons-collections todo : get rid of commons-collections dependency
|
// Jakarta commons-collections todo : get rid of commons-collections dependency
|
||||||
commons_collections:
|
commons_collections:
|
||||||
|
@ -53,6 +54,7 @@ libraries = [
|
||||||
|
|
||||||
// Dom4J
|
// Dom4J
|
||||||
dom4j: 'dom4j:dom4j:1.6.1@jar',
|
dom4j: 'dom4j:dom4j:1.6.1@jar',
|
||||||
|
jaxb: 'com.sun.xml.bind:jaxb-xjc:2.1.6',
|
||||||
|
|
||||||
// h2
|
// h2
|
||||||
h2: 'com.h2database:h2:1.2.145',
|
h2: 'com.h2database:h2:1.2.145',
|
||||||
|
@ -114,11 +116,14 @@ subprojects { subProject ->
|
||||||
deployerJars {
|
deployerJars {
|
||||||
description = 'Jars needed for doing deployment to JBoss Nexus repo'
|
description = 'Jars needed for doing deployment to JBoss Nexus repo'
|
||||||
}
|
}
|
||||||
|
jaxb {
|
||||||
|
description = 'Dependencies for running ant xjc (jaxb class generation)'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 )
|
||||||
testCompile( libraries.junit )
|
testCompile( libraries.junit )
|
||||||
testRuntime( libraries.slf4j_api )
|
testRuntime( libraries.slf4j_api )
|
||||||
testRuntime( libraries.slf4j_log4j12 )
|
testRuntime( libraries.slf4j_log4j12 )
|
||||||
|
@ -127,8 +132,9 @@ subprojects { subProject ->
|
||||||
testRuntime( libraries.jcl )
|
testRuntime( libraries.jcl )
|
||||||
testRuntime( libraries.javassist )
|
testRuntime( libraries.javassist )
|
||||||
testRuntime( libraries.h2 )
|
testRuntime( libraries.h2 )
|
||||||
jbossLoggingTool( libraries.logging_tools )
|
jbossLoggingTool( libraries.logging_tools )
|
||||||
hibernateJpaModelGenTool( libraries.jpa_modelgen )
|
hibernateJpaModelGenTool( libraries.jpa_modelgen )
|
||||||
|
jaxb( libraries.jaxb )
|
||||||
deployerJars "org.apache.maven.wagon:wagon-http:1.0-beta-6"
|
deployerJars "org.apache.maven.wagon:wagon-http:1.0-beta-6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ dependencies {
|
||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
compile( libraries.commons_annotations )
|
compile( libraries.commons_annotations )
|
||||||
|
compile( libraries.jandex )
|
||||||
compile( libraries.jpa )
|
compile( libraries.jpa )
|
||||||
compile( libraries.javassist )
|
compile( libraries.javassist )
|
||||||
antlr( libraries.antlr )
|
antlr( libraries.antlr )
|
||||||
|
@ -43,3 +44,16 @@ ideaModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
task jaxb << {
|
||||||
|
jaxbTargetDir = file( "${buildDir}/generated-src/jaxb" )
|
||||||
|
jaxbTargetDir.mkdirs()
|
||||||
|
|
||||||
|
ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.jaxb.asPath)
|
||||||
|
ant.jaxbTargetDir = jaxbTargetDir
|
||||||
|
ant.xjc(destdir: '${jaxbTargetDir}', package: 'org.hibernate.metamodel.source.xml') {
|
||||||
|
schema(dir: 'src/main/resources/org/hibernate/ejb', includes: 'orm_2_0.xsd')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileJava.dependsOn jaxb
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* Binds the entity identifier.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +42,8 @@ public class EntityIdentifier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an identifier
|
* Create an identifier
|
||||||
* @param entityBinding
|
*
|
||||||
|
* @param entityBinding the entity binding for which this instance is the id
|
||||||
*/
|
*/
|
||||||
public EntityIdentifier(EntityBinding entityBinding) {
|
public EntityIdentifier(EntityBinding entityBinding) {
|
||||||
this.entityBinding = entityBinding;
|
this.entityBinding = entityBinding;
|
||||||
|
@ -54,7 +55,8 @@ public class EntityIdentifier {
|
||||||
|
|
||||||
public void setValueBinding(AttributeBinding attributeBinding) {
|
public void setValueBinding(AttributeBinding attributeBinding) {
|
||||||
if ( this.attributeBinding != null ) {
|
if ( this.attributeBinding != null ) {
|
||||||
// todo : error? or just log? for now just log
|
// todo : error? or just log? For now throw exception and see what happens. Easier to see whether this
|
||||||
|
// method gets called multiple times
|
||||||
LOG.entityIdentifierValueBindingExists( entityBinding.getEntity().getName() );
|
LOG.entityIdentifierValueBindingExists( entityBinding.getEntity().getName() );
|
||||||
}
|
}
|
||||||
this.attributeBinding = attributeBinding;
|
this.attributeBinding = attributeBinding;
|
||||||
|
|
|
@ -29,23 +29,21 @@ import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.hibernate.DuplicateMappingException;
|
import org.hibernate.DuplicateMappingException;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
|
||||||
import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
|
|
||||||
import org.hibernate.annotations.common.reflection.ReflectionManager;
|
|
||||||
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
|
|
||||||
import org.hibernate.cfg.EJB3NamingStrategy;
|
import org.hibernate.cfg.EJB3NamingStrategy;
|
||||||
import org.hibernate.cfg.NamingStrategy;
|
import org.hibernate.cfg.NamingStrategy;
|
||||||
import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
|
|
||||||
import org.hibernate.mapping.FetchProfile;
|
import org.hibernate.mapping.FetchProfile;
|
||||||
import org.hibernate.mapping.MetadataSource;
|
import org.hibernate.mapping.MetadataSource;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
import org.hibernate.metamodel.binding.PluralAttributeBinding;
|
||||||
import org.hibernate.metamodel.relational.Database;
|
import org.hibernate.metamodel.relational.Database;
|
||||||
|
import org.hibernate.metamodel.source.annotations.AnnotationBinder;
|
||||||
import org.hibernate.metamodel.source.hbm.HibernateXmlBinder;
|
import org.hibernate.metamodel.source.hbm.HibernateXmlBinder;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* TODO : javadoc
|
||||||
|
@ -53,19 +51,36 @@ import org.jboss.logging.Logger;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class Metadata implements Serializable {
|
public class Metadata implements Serializable {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( Metadata.class );
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Metadata.class.getName());
|
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, Metadata.class.getName());
|
||||||
|
private final AnnotationBinder annotationBinder;
|
||||||
|
private final HibernateXmlBinder hibernateXmlBinder;
|
||||||
|
private final ExtendsQueue extendsQueue;
|
||||||
|
private final MetadataSourceQueue metadataSourceQueue;
|
||||||
|
private final Database database = new Database();
|
||||||
|
|
||||||
private final HibernateXmlBinder hibernateXmlBinder = new HibernateXmlBinder( this );
|
private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE;
|
||||||
private final ExtendsQueue extendsQueue = new ExtendsQueue( this );
|
private Map<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
|
||||||
private final MetadataSourceQueue metadataSourceQueue = new MetadataSourceQueue( this );
|
private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
|
||||||
|
private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
|
||||||
|
private Map<String, String> imports;
|
||||||
|
|
||||||
private transient ReflectionManager reflectionManager = createReflectionManager();
|
public Metadata() {
|
||||||
|
annotationBinder = new AnnotationBinder( this );
|
||||||
|
hibernateXmlBinder = new HibernateXmlBinder( this );
|
||||||
|
extendsQueue = new ExtendsQueue( this );
|
||||||
|
metadataSourceQueue = new MetadataSourceQueue( this );
|
||||||
|
}
|
||||||
|
|
||||||
public HibernateXmlBinder getHibernateXmlBinder() {
|
public HibernateXmlBinder getHibernateXmlBinder() {
|
||||||
return hibernateXmlBinder;
|
return hibernateXmlBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AnnotationBinder getAnnotationBinder() {
|
||||||
|
return annotationBinder;
|
||||||
|
}
|
||||||
|
|
||||||
public ExtendsQueue getExtendsQueue() {
|
public ExtendsQueue getExtendsQueue() {
|
||||||
return extendsQueue;
|
return extendsQueue;
|
||||||
}
|
}
|
||||||
|
@ -74,32 +89,10 @@ public class Metadata implements Serializable {
|
||||||
return metadataSourceQueue;
|
return metadataSourceQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReflectionManager getReflectionManager() {
|
|
||||||
return reflectionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReflectionManager(ReflectionManager reflectionManager) {
|
|
||||||
this.reflectionManager = reflectionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ReflectionManager createReflectionManager() {
|
|
||||||
return createReflectionManager( new JPAMetadataProvider() );
|
|
||||||
}
|
|
||||||
|
|
||||||
private ReflectionManager createReflectionManager(MetadataProvider metadataProvider) {
|
|
||||||
ReflectionManager reflectionManager = new JavaReflectionManager();
|
|
||||||
( (MetadataProviderInjector) reflectionManager ).setMetadataProvider( metadataProvider );
|
|
||||||
return reflectionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Database database = new Database();
|
|
||||||
|
|
||||||
public Database getDatabase() {
|
public Database getDatabase() {
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE;
|
|
||||||
|
|
||||||
public NamingStrategy getNamingStrategy() {
|
public NamingStrategy getNamingStrategy() {
|
||||||
return namingStrategy;
|
return namingStrategy;
|
||||||
}
|
}
|
||||||
|
@ -108,8 +101,6 @@ public class Metadata implements Serializable {
|
||||||
this.namingStrategy = namingStrategy;
|
this.namingStrategy = namingStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String,EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();
|
|
||||||
|
|
||||||
public EntityBinding getEntityBinding(String entityName) {
|
public EntityBinding getEntityBinding(String entityName) {
|
||||||
return entityBindingMap.get( entityName );
|
return entityBindingMap.get( entityName );
|
||||||
}
|
}
|
||||||
|
@ -126,8 +117,6 @@ public class Metadata implements Serializable {
|
||||||
entityBindingMap.put( entityName, entityBinding );
|
entityBindingMap.put( entityName, entityBinding );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String,PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
|
|
||||||
|
|
||||||
public PluralAttributeBinding getCollection(String collectionRole) {
|
public PluralAttributeBinding getCollection(String collectionRole) {
|
||||||
return collectionBindingMap.get( collectionRole );
|
return collectionBindingMap.get( collectionRole );
|
||||||
}
|
}
|
||||||
|
@ -146,21 +135,17 @@ public class Metadata implements Serializable {
|
||||||
collectionBindingMap.put( collectionRole, pluralAttributeBinding );
|
collectionBindingMap.put( collectionRole, pluralAttributeBinding );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String,String> imports;
|
|
||||||
|
|
||||||
public void addImport(String importName, String entityName) {
|
public void addImport(String importName, String entityName) {
|
||||||
if ( imports == null ) {
|
if ( imports == null ) {
|
||||||
imports = new HashMap<String, String>();
|
imports = new HashMap<String, String>();
|
||||||
}
|
}
|
||||||
LOG.tracef( "Import: %s -> %s", importName, entityName );
|
log.trace( "Import: " + importName + " -> " + entityName );
|
||||||
String old = imports.put( importName, entityName );
|
String old = imports.put( importName, entityName );
|
||||||
if ( old != null ) {
|
if ( old != null ) {
|
||||||
LOG.debugf( "import name [%s] overrode previous [%s]", importName, old );
|
log.debug( "import name [{}] overrode previous [{}]", importName, old );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String,FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
|
|
||||||
|
|
||||||
public Iterable<FetchProfile> getFetchProfiles() {
|
public Iterable<FetchProfile> getFetchProfiles() {
|
||||||
return fetchProfiles.values();
|
return fetchProfiles.values();
|
||||||
}
|
}
|
||||||
|
@ -175,16 +160,10 @@ public class Metadata implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||||
//we need reflectionManager before reading the other components (MetadataSourceQueue in particular)
|
|
||||||
final MetadataProvider metadataProvider = (MetadataProvider) ois.readObject();
|
|
||||||
this.reflectionManager = createReflectionManager( metadataProvider );
|
|
||||||
ois.defaultReadObject();
|
ois.defaultReadObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
||||||
//We write MetadataProvider first as we need reflectionManager before reading the other components
|
|
||||||
final MetadataProvider metadataProvider = ( ( MetadataProviderInjector ) reflectionManager ).getMetadataProvider();
|
|
||||||
out.writeObject( metadataProvider );
|
|
||||||
out.defaultWriteObject();
|
out.defaultWriteObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,20 +34,20 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.Entity;
|
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.InvalidMappingException;
|
import org.hibernate.InvalidMappingException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.common.reflection.XClass;
|
|
||||||
import org.hibernate.cfg.MetadataSourceType;
|
import org.hibernate.cfg.MetadataSourceType;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
import org.hibernate.internal.util.xml.XmlDocument;
|
import org.hibernate.internal.util.xml.XmlDocument;
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO : javadoc
|
* TODO : javadoc
|
||||||
|
@ -55,19 +55,14 @@ import org.jboss.logging.Logger;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class MetadataSourceQueue implements Serializable {
|
public class MetadataSourceQueue implements Serializable {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( MetadataSourceQueue.class );
|
||||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataSourceQueue.class.getName());
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, MetadataSourceQueue.class.getName());
|
||||||
|
|
||||||
private final Metadata metadata;
|
private final Metadata metadata;
|
||||||
|
|
||||||
private LinkedHashMap<XmlDocument, Set<String>> hbmMetadataToEntityNamesMap
|
private LinkedHashMap<XmlDocument, Set<String>> hbmMetadataToEntityNamesMap
|
||||||
= new LinkedHashMap<XmlDocument, Set<String>>();
|
= new LinkedHashMap<XmlDocument, Set<String>>();
|
||||||
private Map<String, XmlDocument> hbmMetadataByEntityNameXRef = new HashMap<String, XmlDocument>();
|
private Map<String, XmlDocument> hbmMetadataByEntityNameXRef = new HashMap<String, XmlDocument>();
|
||||||
|
private transient List<Class> annotatedClasses = new ArrayList<Class>();
|
||||||
//XClass are not serializable by default
|
|
||||||
private transient List<XClass> annotatedClasses = new ArrayList<XClass>();
|
|
||||||
//only used during the secondPhaseCompile pass, hence does not need to be serialized
|
|
||||||
private transient Map<String, XClass> annotatedClassesByEntityNameMap = new HashMap<String, XClass>();
|
|
||||||
|
|
||||||
public MetadataSourceQueue(Metadata metadata) {
|
public MetadataSourceQueue(Metadata metadata) {
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
|
@ -75,24 +70,10 @@ public class MetadataSourceQueue implements Serializable {
|
||||||
|
|
||||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||||
ois.defaultReadObject();
|
ois.defaultReadObject();
|
||||||
annotatedClassesByEntityNameMap = new HashMap<String, XClass>();
|
|
||||||
|
|
||||||
//build back annotatedClasses
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
List<Class> serializableAnnotatedClasses = (List<Class>) ois.readObject();
|
|
||||||
annotatedClasses = new ArrayList<XClass>( serializableAnnotatedClasses.size() );
|
|
||||||
for ( Class clazz : serializableAnnotatedClasses ) {
|
|
||||||
annotatedClasses.add( metadata.getReflectionManager().toXClass( clazz ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
|
||||||
out.defaultWriteObject();
|
out.defaultWriteObject();
|
||||||
List<Class> serializableAnnotatedClasses = new ArrayList<Class>( annotatedClasses.size() );
|
|
||||||
for ( XClass xClass : annotatedClasses ) {
|
|
||||||
serializableAnnotatedClasses.add( metadata.getReflectionManager().toClass( xClass ) );
|
|
||||||
}
|
|
||||||
out.writeObject( serializableAnnotatedClasses );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(XmlDocument metadataXml) {
|
public void add(XmlDocument metadataXml) {
|
||||||
|
@ -143,28 +124,11 @@ public class MetadataSourceQueue implements Serializable {
|
||||||
return unqualifiedName;
|
return unqualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(XClass annotatedClass) {
|
public void add(Class annotatedClass) {
|
||||||
annotatedClasses.add( annotatedClass );
|
annotatedClasses.add( annotatedClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void syncAnnotatedClasses() {
|
|
||||||
final Iterator<XClass> itr = annotatedClasses.iterator();
|
|
||||||
while ( itr.hasNext() ) {
|
|
||||||
final XClass annotatedClass = itr.next();
|
|
||||||
if ( annotatedClass.isAnnotationPresent( Entity.class ) ) {
|
|
||||||
annotatedClassesByEntityNameMap.put( annotatedClass.getName(), annotatedClass );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !annotatedClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) {
|
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void processMetadata(List<MetadataSourceType> order) {
|
protected void processMetadata(List<MetadataSourceType> order) {
|
||||||
syncAnnotatedClasses();
|
|
||||||
|
|
||||||
for ( MetadataSourceType type : order ) {
|
for ( MetadataSourceType type : order ) {
|
||||||
if ( MetadataSourceType.HBM.equals( type ) ) {
|
if ( MetadataSourceType.HBM.equals( type ) ) {
|
||||||
processHbmXmlQueue();
|
processHbmXmlQueue();
|
||||||
|
@ -176,7 +140,7 @@ public class MetadataSourceQueue implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processHbmXmlQueue() {
|
private void processHbmXmlQueue() {
|
||||||
LOG.debug( "Processing hbm.xml files" );
|
log.debug( "Processing hbm.xml files" );
|
||||||
for ( Map.Entry<XmlDocument, Set<String>> entry : hbmMetadataToEntityNamesMap.entrySet() ) {
|
for ( Map.Entry<XmlDocument, Set<String>> entry : hbmMetadataToEntityNamesMap.entrySet() ) {
|
||||||
// Unfortunately we have to create a Mappings instance for each iteration here
|
// Unfortunately we have to create a Mappings instance for each iteration here
|
||||||
processHbmXml( entry.getKey(), entry.getValue() );
|
processHbmXml( entry.getKey(), entry.getValue() );
|
||||||
|
@ -196,83 +160,14 @@ public class MetadataSourceQueue implements Serializable {
|
||||||
me
|
me
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( String entityName : entityNames ) {
|
|
||||||
if ( annotatedClassesByEntityNameMap.containsKey( entityName ) ) {
|
|
||||||
annotatedClasses.remove( annotatedClassesByEntityNameMap.get( entityName ) );
|
|
||||||
annotatedClassesByEntityNameMap.remove( entityName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processAnnotatedClassesQueue() {
|
private void processAnnotatedClassesQueue() {
|
||||||
LOG.debug( "Process annotated classes" );
|
log.debug( "Process annotated classes" );
|
||||||
//bind classes in the correct order calculating some inheritance state
|
|
||||||
List<XClass> orderedClasses = orderAndFillHierarchy( annotatedClasses );
|
|
||||||
// Map<XClass, InheritanceState> inheritanceStatePerClass = AnnotationBinder.buildInheritanceStates(
|
|
||||||
// orderedClasses, mappings
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
for ( XClass clazz : orderedClasses ) {
|
|
||||||
// todo : replace this with similar non-static code.
|
|
||||||
// AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings );
|
|
||||||
|
|
||||||
final String entityName = clazz.getName();
|
|
||||||
if ( hbmMetadataByEntityNameXRef.containsKey( entityName ) ) {
|
|
||||||
hbmMetadataToEntityNamesMap.remove( hbmMetadataByEntityNameXRef.get( entityName ) );
|
|
||||||
hbmMetadataByEntityNameXRef.remove( entityName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
annotatedClasses.clear();
|
annotatedClasses.clear();
|
||||||
annotatedClassesByEntityNameMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<XClass> orderAndFillHierarchy(List<XClass> original) {
|
|
||||||
List<XClass> copy = new ArrayList<XClass>( original );
|
|
||||||
insertMappedSuperclasses( original, copy );
|
|
||||||
|
|
||||||
// order the hierarchy
|
|
||||||
List<XClass> workingCopy = new ArrayList<XClass>( copy );
|
|
||||||
List<XClass> newList = new ArrayList<XClass>( copy.size() );
|
|
||||||
while ( workingCopy.size() > 0 ) {
|
|
||||||
XClass clazz = workingCopy.get( 0 );
|
|
||||||
orderHierarchy( workingCopy, newList, copy, clazz );
|
|
||||||
}
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertMappedSuperclasses(List<XClass> original, List<XClass> copy) {
|
|
||||||
for ( XClass clazz : original ) {
|
|
||||||
XClass superClass = clazz.getSuperclass();
|
|
||||||
while ( superClass != null
|
|
||||||
&& !metadata.getReflectionManager().equals( superClass, Object.class )
|
|
||||||
&& !copy.contains( superClass ) ) {
|
|
||||||
if ( superClass.isAnnotationPresent( Entity.class )
|
|
||||||
|| superClass.isAnnotationPresent( javax.persistence.MappedSuperclass.class ) ) {
|
|
||||||
copy.add( superClass );
|
|
||||||
}
|
|
||||||
superClass = superClass.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void orderHierarchy(List<XClass> copy, List<XClass> newList, List<XClass> original, XClass clazz) {
|
|
||||||
if ( clazz == null || metadata.getReflectionManager().equals( clazz, Object.class ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//process superclass first
|
|
||||||
orderHierarchy( copy, newList, original, clazz.getSuperclass() );
|
|
||||||
if ( original.contains( clazz ) ) {
|
|
||||||
if ( !newList.contains( clazz ) ) {
|
|
||||||
newList.add( clazz );
|
|
||||||
}
|
|
||||||
copy.remove( clazz );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return hbmMetadataToEntityNamesMap.isEmpty() && annotatedClasses.isEmpty();
|
return hbmMetadataToEntityNamesMap.isEmpty() && annotatedClasses.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,336 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.MappedSuperclass;
|
||||||
|
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.hibernate.AnnotationException;
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.metamodel.source.Metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main class responsible to creating and binding the Hibernate meta-model from annotations.
|
||||||
|
* This binder only has to deal with annotation index. XML configuration is already processed and pseudo annotations
|
||||||
|
* are added to the annotation index.
|
||||||
|
*
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
* @todo On top of the index we probably needs to pass some sort of XMLContext for global configuration data
|
||||||
|
* @todo The annotation index should really be passed at construction time
|
||||||
|
*/
|
||||||
|
public class AnnotationBinder {
|
||||||
|
public static final DotName ENTITY = DotName.createSimple( Entity.class.getName() );
|
||||||
|
public static final DotName HIBERNATE_ENTITY = DotName.createSimple( org.hibernate.annotations.Entity.class.getName() );
|
||||||
|
public static final DotName MAPPED_SUPER_CLASS = DotName.createSimple( MappedSuperclass.class.getName() );
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
|
||||||
|
private final Metadata metadata;
|
||||||
|
|
||||||
|
public AnnotationBinder(Metadata metadata) {
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindMappedClasses(Index annotationIndex) {
|
||||||
|
// need to order our annotated entities into an order we can process
|
||||||
|
EntityHierarchyBuilder builder = new EntityHierarchyBuilder();
|
||||||
|
List<EntityHierarchy> hierarchies = builder.createEntityHierarchies( annotationIndex );
|
||||||
|
|
||||||
|
// now we process each hierarchy one at the time
|
||||||
|
for ( EntityHierarchy hierarchy : hierarchies ) {
|
||||||
|
Iterator<Entity> iter = hierarchy.iterator();
|
||||||
|
while ( iter.hasNext() ) {
|
||||||
|
Entity entity = iter.next();
|
||||||
|
bindEntity( entity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindEntity(Entity entity) {
|
||||||
|
ClassInfo classInfo = entity.getClassInfo();
|
||||||
|
|
||||||
|
//@Entity and @MappedSuperclass on the same class leads to a NPE down the road
|
||||||
|
AnnotationInstance jpaEntityAnnotation = getSingleAnnotation( classInfo, ENTITY );
|
||||||
|
AnnotationInstance mappedSuperClassAnnotation = getSingleAnnotation( classInfo, MAPPED_SUPER_CLASS );
|
||||||
|
AnnotationInstance hibernateEntityAnnotation = getSingleAnnotation( classInfo, HIBERNATE_ENTITY );
|
||||||
|
|
||||||
|
if ( jpaEntityAnnotation != null && mappedSuperClassAnnotation != null ) {
|
||||||
|
throw new AnnotationException(
|
||||||
|
"An entity cannot be annotated with both @Entity and @MappedSuperclass: "
|
||||||
|
+ classInfo.name().toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// //TODO: be more strict with secondarytable allowance (not for ids, not for secondary table join columns etc)
|
||||||
|
// InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
|
||||||
|
// AnnotatedClassType classType = mappings.getClassType( clazzToProcess );
|
||||||
|
//
|
||||||
|
// //Queries declared in MappedSuperclass should be usable in Subclasses
|
||||||
|
// if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
|
||||||
|
// bindQueries( clazzToProcess, mappings );
|
||||||
|
// bindTypeDefs( clazzToProcess, mappings );
|
||||||
|
// bindFilterDefs( clazzToProcess, mappings );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if ( !isEntityClassType( clazzToProcess, classType ) ) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
log.info( "Binding entity from annotated class: {}", classInfo.name() );
|
||||||
|
//
|
||||||
|
// PersistentClass superEntity = getSuperEntity(
|
||||||
|
// clazzToProcess, inheritanceStatePerClass, mappings, inheritanceState
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity );
|
||||||
|
|
||||||
|
|
||||||
|
EntityBinder entityBinder = new EntityBinder(
|
||||||
|
metadata, classInfo, jpaEntityAnnotation, hibernateEntityAnnotation
|
||||||
|
);
|
||||||
|
// entityBinder.setInheritanceState( inheritanceState );
|
||||||
|
//
|
||||||
|
// bindQueries( clazzToProcess, mappings );
|
||||||
|
// bindFilterDefs( clazzToProcess, mappings );
|
||||||
|
// bindTypeDefs( clazzToProcess, mappings );
|
||||||
|
// bindFetchProfiles( clazzToProcess, mappings );
|
||||||
|
// BinderHelper.bindAnyMetaDefs( clazzToProcess, mappings );
|
||||||
|
//
|
||||||
|
// String schema = "";
|
||||||
|
// String table = ""; //might be no @Table annotation on the annotated class
|
||||||
|
// String catalog = "";
|
||||||
|
// List<UniqueConstraintHolder> uniqueConstraints = new ArrayList<UniqueConstraintHolder>();
|
||||||
|
// if ( clazzToProcess.isAnnotationPresent( javax.persistence.Table.class ) ) {
|
||||||
|
// javax.persistence.Table tabAnn = clazzToProcess.getAnnotation( javax.persistence.Table.class );
|
||||||
|
// table = tabAnn.name();
|
||||||
|
// schema = tabAnn.schema();
|
||||||
|
// catalog = tabAnn.catalog();
|
||||||
|
// uniqueConstraints = TableBinder.buildUniqueConstraintHolders( tabAnn.uniqueConstraints() );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns(
|
||||||
|
// clazzToProcess, mappings, inheritanceState, superEntity
|
||||||
|
// );
|
||||||
|
// Ejb3DiscriminatorColumn discriminatorColumn = null;
|
||||||
|
// if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
|
||||||
|
// discriminatorColumn = processDiscriminatorProperties(
|
||||||
|
// clazzToProcess, mappings, inheritanceState, entityBinder
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// entityBinder.setProxy( clazzToProcess.getAnnotation( Proxy.class ) );
|
||||||
|
// entityBinder.setBatchSize( clazzToProcess.getAnnotation( BatchSize.class ) );
|
||||||
|
// entityBinder.setWhere( clazzToProcess.getAnnotation( Where.class ) );
|
||||||
|
// entityBinder.setCache( determineCacheSettings( clazzToProcess, mappings ) );
|
||||||
|
//
|
||||||
|
// //Filters are not allowed on subclasses
|
||||||
|
// if ( !inheritanceState.hasParents() ) {
|
||||||
|
// bindFilters( clazzToProcess, entityBinder, mappings );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// entityBinder.bindEntity();
|
||||||
|
//
|
||||||
|
// if ( inheritanceState.hasTable() ) {
|
||||||
|
// Check checkAnn = clazzToProcess.getAnnotation( Check.class );
|
||||||
|
// String constraints = checkAnn == null ?
|
||||||
|
// null :
|
||||||
|
// checkAnn.constraints();
|
||||||
|
// entityBinder.bindTable(
|
||||||
|
// schema, catalog, table, uniqueConstraints,
|
||||||
|
// constraints, inheritanceState.hasDenormalizedTable() ?
|
||||||
|
// superEntity.getTable() :
|
||||||
|
// null
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// if ( clazzToProcess.isAnnotationPresent( Table.class ) ) {
|
||||||
|
// log.warn(
|
||||||
|
// "Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy: " + clazzToProcess
|
||||||
|
// .getName()
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(
|
||||||
|
// clazzToProcess,
|
||||||
|
// persistentClass,
|
||||||
|
// entityBinder, mappings, inheritanceStatePerClass
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(
|
||||||
|
// javax.persistence.SecondaryTable.class
|
||||||
|
// );
|
||||||
|
// javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(
|
||||||
|
// javax.persistence.SecondaryTables.class
|
||||||
|
// );
|
||||||
|
// entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn );
|
||||||
|
//
|
||||||
|
// OnDelete onDeleteAnn = clazzToProcess.getAnnotation( OnDelete.class );
|
||||||
|
// boolean onDeleteAppropriate = false;
|
||||||
|
// if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) && inheritanceState.hasParents() ) {
|
||||||
|
// onDeleteAppropriate = true;
|
||||||
|
// final JoinedSubclass jsc = ( JoinedSubclass ) persistentClass;
|
||||||
|
// if ( persistentClass.getEntityPersisterClass() == null ) {
|
||||||
|
// persistentClass.getRootClass().setEntityPersisterClass( JoinedSubclassEntityPersister.class );
|
||||||
|
// }
|
||||||
|
// SimpleValue key = new DependantValue( mappings, jsc.getTable(), jsc.getIdentifier() );
|
||||||
|
// jsc.setKey( key );
|
||||||
|
// ForeignKey fk = clazzToProcess.getAnnotation( ForeignKey.class );
|
||||||
|
// if ( fk != null && !BinderHelper.isEmptyAnnotationValue( fk.name() ) ) {
|
||||||
|
// key.setForeignKeyName( fk.name() );
|
||||||
|
// }
|
||||||
|
// if ( onDeleteAnn != null ) {
|
||||||
|
// key.setCascadeDeleteEnabled( OnDeleteAction.CASCADE.equals( onDeleteAnn.action() ) );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// key.setCascadeDeleteEnabled( false );
|
||||||
|
// }
|
||||||
|
// //we are never in a second pass at that stage, so queue it
|
||||||
|
// SecondPass sp = new JoinedSubclassFkSecondPass( jsc, inheritanceJoinedColumns, key, mappings );
|
||||||
|
// mappings.addSecondPass( sp );
|
||||||
|
// mappings.addSecondPass( new CreateKeySecondPass( jsc ) );
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
|
||||||
|
// if ( inheritanceState.hasParents() ) {
|
||||||
|
// if ( persistentClass.getEntityPersisterClass() == null ) {
|
||||||
|
// persistentClass.getRootClass().setEntityPersisterClass( SingleTableEntityPersister.class );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// if ( inheritanceState.hasSiblings() || !discriminatorColumn.isImplicit() ) {
|
||||||
|
// //need a discriminator column
|
||||||
|
// bindDiscriminatorToPersistentClass(
|
||||||
|
// (RootClass) persistentClass,
|
||||||
|
// discriminatorColumn,
|
||||||
|
// entityBinder.getSecondaryTables(),
|
||||||
|
// propertyHolder,
|
||||||
|
// mappings
|
||||||
|
// );
|
||||||
|
// entityBinder.bindDiscriminatorValue();//bind it again since the type might have changed
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
|
||||||
|
// if ( inheritanceState.hasParents() ) {
|
||||||
|
// if ( persistentClass.getEntityPersisterClass() == null ) {
|
||||||
|
// persistentClass.getRootClass().setEntityPersisterClass( UnionSubclassEntityPersister.class );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if ( onDeleteAnn != null && !onDeleteAppropriate ) {
|
||||||
|
// log.warn(
|
||||||
|
// "Inapropriate use of @OnDelete on entity, annotation ignored: {}", propertyHolder.getEntityName()
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // try to find class level generators
|
||||||
|
// HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( clazzToProcess, mappings );
|
||||||
|
//
|
||||||
|
// // check properties
|
||||||
|
// final InheritanceState.ElementsToProcess elementsToProcess = inheritanceState.getElementsToProcess();
|
||||||
|
// inheritanceState.postProcess( persistentClass, entityBinder );
|
||||||
|
//
|
||||||
|
// final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE
|
||||||
|
// && inheritanceState.hasParents();
|
||||||
|
// Set<String> idPropertiesIfIdClass = new HashSet<String>();
|
||||||
|
// boolean isIdClass = mapAsIdClass(
|
||||||
|
// inheritanceStatePerClass,
|
||||||
|
// inheritanceState,
|
||||||
|
// persistentClass,
|
||||||
|
// entityBinder,
|
||||||
|
// propertyHolder,
|
||||||
|
// elementsToProcess,
|
||||||
|
// idPropertiesIfIdClass,
|
||||||
|
// mappings
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if ( !isIdClass ) {
|
||||||
|
// entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount() > 1 );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// processIdPropertiesIfNotAlready(
|
||||||
|
// inheritanceStatePerClass,
|
||||||
|
// mappings,
|
||||||
|
// persistentClass,
|
||||||
|
// entityBinder,
|
||||||
|
// propertyHolder,
|
||||||
|
// classGenerators,
|
||||||
|
// elementsToProcess,
|
||||||
|
// subclassAndSingleTableStrategy,
|
||||||
|
// idPropertiesIfIdClass
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if ( !inheritanceState.hasParents() ) {
|
||||||
|
// final RootClass rootClass = ( RootClass ) persistentClass;
|
||||||
|
// mappings.addSecondPass( new CreateKeySecondPass( rootClass ) );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// superEntity.addSubclass( (Subclass) persistentClass );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// mappings.addClass( persistentClass );
|
||||||
|
//
|
||||||
|
// //Process secondary tables and complementary definitions (ie o.h.a.Table)
|
||||||
|
// mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder, clazzToProcess ) );
|
||||||
|
//
|
||||||
|
// //add process complementary Table definition (index & all)
|
||||||
|
// entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Table.class ) );
|
||||||
|
// entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Tables.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param classInfo the class info from which to retrieve the annotation instance
|
||||||
|
* @param annotationName the annotation to retrieve from the class info
|
||||||
|
*
|
||||||
|
* @return the single annotation defined on the class or {@code null} in case the annotation is not specified at all
|
||||||
|
*
|
||||||
|
* @throws AssertionFailure in case there is
|
||||||
|
*/
|
||||||
|
private AnnotationInstance getSingleAnnotation(ClassInfo classInfo, DotName annotationName)
|
||||||
|
throws AssertionFailure {
|
||||||
|
List<AnnotationInstance> annotationList = classInfo.annotations().get( annotationName );
|
||||||
|
if ( annotationList == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if ( annotationList.size() == 1 ) {
|
||||||
|
return annotationList.get( 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new AssertionFailure(
|
||||||
|
"There should be only one annotation of type " + annotationName + " defined on" + classInfo.name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an entity or mapped superclass which needs to be mapped.
|
||||||
|
*
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class Entity {
|
||||||
|
private ClassInfo classInfo;
|
||||||
|
|
||||||
|
public ClassInfo getClassInfo() {
|
||||||
|
return classInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
|
||||||
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
|
import org.hibernate.metamodel.domain.Entity;
|
||||||
|
import org.hibernate.metamodel.source.Metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class EntityBinder {
|
||||||
|
private final ClassInfo classToBind;
|
||||||
|
|
||||||
|
public EntityBinder(Metadata metadata, ClassInfo classInfo, AnnotationInstance jpaEntityAnnotation, AnnotationInstance hibernateEntityAnnotation) {
|
||||||
|
this.classToBind = classInfo;
|
||||||
|
EntityBinding entityBinding = new EntityBinding();
|
||||||
|
bindJpaAnnotation( jpaEntityAnnotation, entityBinding );
|
||||||
|
bindHibernateAnnotation( hibernateEntityAnnotation, entityBinding );
|
||||||
|
metadata.addEntity( entityBinding );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindHibernateAnnotation(AnnotationInstance annotation, EntityBinding entityBinding) {
|
||||||
|
// if ( hibAnn != null ) {
|
||||||
|
// dynamicInsert = hibAnn.dynamicInsert();
|
||||||
|
// dynamicUpdate = hibAnn.dynamicUpdate();
|
||||||
|
// optimisticLockType = hibAnn.optimisticLock();
|
||||||
|
// selectBeforeUpdate = hibAnn.selectBeforeUpdate();
|
||||||
|
// polymorphismType = hibAnn.polymorphism();
|
||||||
|
// explicitHibernateEntityAnnotation = true;
|
||||||
|
// //persister handled in bind
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// //default values when the annotation is not there
|
||||||
|
// dynamicInsert = false;
|
||||||
|
// dynamicUpdate = false;
|
||||||
|
// optimisticLockType = OptimisticLockType.VERSION;
|
||||||
|
// polymorphismType = PolymorphismType.IMPLICIT;
|
||||||
|
// selectBeforeUpdate = false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindJpaAnnotation(AnnotationInstance annotation, EntityBinding entityBinding) {
|
||||||
|
if ( annotation == null ) {
|
||||||
|
throw new AssertionFailure( "@Entity cannot be not null when binding an entity" );
|
||||||
|
}
|
||||||
|
String name;
|
||||||
|
if ( annotation.value( "name" ) == null ) {
|
||||||
|
name = StringHelper.unqualify( classToBind.name().toString() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = annotation.value( "name" ).asString();
|
||||||
|
}
|
||||||
|
entityBinding.setEntity( new Entity( name, null ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class EntityHierarchy implements Iterable<Entity> {
|
||||||
|
@Override
|
||||||
|
public Iterator<Entity> iterator() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a annotation index build a list of entity hierarchies.
|
||||||
|
*
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class EntityHierarchyBuilder {
|
||||||
|
public List<EntityHierarchy> createEntityHierarchies(Index index) {
|
||||||
|
List<EntityHierarchy> hierarchies = new ArrayList<EntityHierarchy>();
|
||||||
|
|
||||||
|
|
||||||
|
return hierarchies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.validation.ValidationException;
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBElement;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
import javax.xml.validation.Schema;
|
||||||
|
import javax.xml.validation.SchemaFactory;
|
||||||
|
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.source.xml.EntityMappings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
* @todo Need some create some XMLContext as well which can be populated w/ information which can not be expressed via annotations
|
||||||
|
*/
|
||||||
|
public class OrmXmlParser {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( OrmXmlParser.class );
|
||||||
|
private static final String ORM_MAPPING_XSD = "org/hibernate/ejb/orm_2_0.xsd";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given xml configuration files and returns a updated annotation index
|
||||||
|
*
|
||||||
|
* @param mappingFileNames the file names of the xml files to parse
|
||||||
|
* @param annotationIndex the annotation index based on scanned annotations
|
||||||
|
*
|
||||||
|
* @return a new updated annotation index, enhancing and modifying the existing ones according to the jpa xml rules
|
||||||
|
*/
|
||||||
|
public Index parseAndUpdateIndex(Set<String> mappingFileNames, Index annotationIndex) {
|
||||||
|
|
||||||
|
Set<InputStream> mappingStreams = new HashSet<InputStream>();
|
||||||
|
for ( String fileName : mappingFileNames ) {
|
||||||
|
mappingStreams.add( getInputStreamForPath( fileName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( InputStream in : mappingStreams ) {
|
||||||
|
EntityMappings entityMappings = getEntityMappings( in );
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getInputStreamForPath(String path) {
|
||||||
|
// try the context class loader first
|
||||||
|
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
|
||||||
|
|
||||||
|
// try the current class loader
|
||||||
|
if ( inputStream == null ) {
|
||||||
|
inputStream = OrmXmlParser.class.getResourceAsStream( path );
|
||||||
|
}
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityMappings getEntityMappings(InputStream in) {
|
||||||
|
EntityMappings entityMappings;
|
||||||
|
Schema schema = getMappingSchema();
|
||||||
|
try {
|
||||||
|
JAXBContext jc = JAXBContext.newInstance( EntityMappings.class );
|
||||||
|
Unmarshaller unmarshaller = jc.createUnmarshaller();
|
||||||
|
unmarshaller.setSchema( schema );
|
||||||
|
StreamSource stream = new StreamSource( in );
|
||||||
|
JAXBElement<EntityMappings> root = unmarshaller.unmarshal( stream, EntityMappings.class );
|
||||||
|
entityMappings = root.getValue();
|
||||||
|
}
|
||||||
|
catch ( JAXBException e ) {
|
||||||
|
String msg = "Error parsing mapping file.";
|
||||||
|
log.error( msg );
|
||||||
|
throw new ValidationException( msg, e );
|
||||||
|
}
|
||||||
|
return entityMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Schema getMappingSchema() {
|
||||||
|
ClassLoader loader = OrmXmlParser.class.getClassLoader();
|
||||||
|
URL schemaUrl = loader.getResource( ORM_MAPPING_XSD );
|
||||||
|
SchemaFactory sf = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
|
||||||
|
Schema schema = null;
|
||||||
|
try {
|
||||||
|
schema = sf.newSchema( schemaUrl );
|
||||||
|
}
|
||||||
|
catch ( SAXException e ) {
|
||||||
|
log.debug( "Unable to create schema for {}: {}", ORM_MAPPING_XSD, e.getMessage() );
|
||||||
|
}
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -568,22 +568,6 @@ abstract class AbstractEntityBinder {
|
||||||
// return prop;
|
// return prop;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected Value processValues(Element identifierElement, TableSpecification baseTable, String propertyPath) {
|
protected Value processValues(Element identifierElement, TableSpecification baseTable, String propertyPath) {
|
||||||
// first boolean (false here) indicates that by default columns are nullable
|
// first boolean (false here) indicates that by default columns are nullable
|
||||||
// second boolean (true here) indicates that by default column names should be guessed
|
// second boolean (true here) indicates that by default column names should be guessed
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.relational.Column;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
import static junit.framework.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic tests of {@code hbm.xml} and annotation binding code
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public abstract class AbstractBasicBindingTests extends BaseUnitTestCase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleEntityMapping() {
|
||||||
|
EntityBinding entityBinding = buildSimpleEntityBinding();
|
||||||
|
assertNotNull( entityBinding );
|
||||||
|
assertNotNull( entityBinding.getEntityIdentifier() );
|
||||||
|
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
|
||||||
|
assertNull( entityBinding.getVersioningValueBinding() );
|
||||||
|
|
||||||
|
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
|
||||||
|
assertNotNull( idAttributeBinding );
|
||||||
|
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
|
||||||
|
assertNotNull( idAttributeBinding.getAttribute() );
|
||||||
|
assertNotNull( idAttributeBinding.getValue() );
|
||||||
|
assertTrue( idAttributeBinding.getValue() instanceof Column );
|
||||||
|
|
||||||
|
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
|
||||||
|
assertNotNull( nameBinding );
|
||||||
|
assertNotNull( nameBinding.getAttribute() );
|
||||||
|
assertNotNull( nameBinding.getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleVersionedEntityMapping() {
|
||||||
|
EntityBinding entityBinding = buildSimpleVersionedEntityBinding();
|
||||||
|
assertNotNull( entityBinding );
|
||||||
|
assertNotNull( entityBinding.getEntityIdentifier() );
|
||||||
|
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
|
||||||
|
assertNotNull( entityBinding.getVersioningValueBinding() );
|
||||||
|
assertNotNull( entityBinding.getVersioningValueBinding().getAttribute() );
|
||||||
|
|
||||||
|
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
|
||||||
|
assertNotNull( idAttributeBinding );
|
||||||
|
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
|
||||||
|
assertNotNull( idAttributeBinding.getAttribute() );
|
||||||
|
assertNotNull( idAttributeBinding.getValue() );
|
||||||
|
assertTrue( idAttributeBinding.getValue() instanceof Column );
|
||||||
|
|
||||||
|
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
|
||||||
|
assertNotNull( nameBinding );
|
||||||
|
assertNotNull( nameBinding.getAttribute() );
|
||||||
|
assertNotNull( nameBinding.getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract EntityBinding buildSimpleVersionedEntityBinding();
|
||||||
|
|
||||||
|
public abstract EntityBinding buildSimpleEntityBinding();
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jboss.jandex.Index;
|
||||||
|
import org.jboss.jandex.Indexer;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.source.Metadata;
|
||||||
|
import org.hibernate.testing.FailureExpected;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic tests of annotation based binding code
|
||||||
|
*
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
|
||||||
|
|
||||||
|
//@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress")
|
||||||
|
@Test
|
||||||
|
public void testSimpleEntityMapping() {
|
||||||
|
super.testSimpleEntityMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress")
|
||||||
|
@Test
|
||||||
|
public void testSimpleVersionedEntityMapping() {
|
||||||
|
super.testSimpleVersionedEntityMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityBinding buildSimpleEntityBinding() {
|
||||||
|
Index index = indexForClass( SimpleEntity.class );
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.getAnnotationBinder().bindMappedClasses( index );
|
||||||
|
|
||||||
|
return metadata.getEntityBinding( SimpleEntity.class.getSimpleName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityBinding buildSimpleVersionedEntityBinding() {
|
||||||
|
Index index = indexForClass( SimpleEntity.class );
|
||||||
|
Metadata metadata = new Metadata();
|
||||||
|
metadata.getAnnotationBinder().bindMappedClasses( index );
|
||||||
|
|
||||||
|
return metadata.getEntityBinding( SimpleVersionedEntity.class.getSimpleName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Index indexForClass(Class<?>... classes) {
|
||||||
|
Indexer indexer = new Indexer();
|
||||||
|
for ( Class<?> clazz : classes ) {
|
||||||
|
InputStream stream = getClass().getClassLoader().getResourceAsStream(
|
||||||
|
clazz.getName().replace( '.', '/' ) + ".class"
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
indexer.index( stream );
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
fail( "Unable to index" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indexer.complete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,75 +30,32 @@ import org.hibernate.internal.util.xml.MappingReader;
|
||||||
import org.hibernate.internal.util.xml.Origin;
|
import org.hibernate.internal.util.xml.Origin;
|
||||||
import org.hibernate.internal.util.xml.XMLHelper;
|
import org.hibernate.internal.util.xml.XMLHelper;
|
||||||
import org.hibernate.internal.util.xml.XmlDocument;
|
import org.hibernate.internal.util.xml.XmlDocument;
|
||||||
import org.hibernate.metamodel.relational.Column;
|
|
||||||
import org.hibernate.metamodel.source.Metadata;
|
import org.hibernate.metamodel.source.Metadata;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertSame;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic tests of {@code hbm.xml} beinding code
|
* Basic tests of {@code hbm.xml} binding code
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class BasicHbmBindingTests extends BaseUnitTestCase {
|
public class BasicHbmBindingTests extends AbstractBasicBindingTests {
|
||||||
@Test
|
|
||||||
public void testSuperSimpleMapping() {
|
public EntityBinding buildSimpleEntityBinding() {
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
|
|
||||||
{
|
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" );
|
||||||
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" );
|
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
|
||||||
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
|
return metadata.getEntityBinding( SimpleEntity.class.getName() );
|
||||||
EntityBinding entityBinding = metadata.getEntityBinding( SimpleEntity.class.getName() );
|
}
|
||||||
assertNotNull( entityBinding );
|
|
||||||
assertNotNull( entityBinding.getEntityIdentifier() );
|
|
||||||
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
|
|
||||||
assertNull( entityBinding.getVersioningValueBinding() );
|
|
||||||
|
|
||||||
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
|
public EntityBinding buildSimpleVersionedEntityBinding() {
|
||||||
assertNotNull( idAttributeBinding );
|
Metadata metadata = new Metadata();
|
||||||
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
|
|
||||||
assertNotNull( idAttributeBinding.getAttribute() );
|
|
||||||
assertNotNull( idAttributeBinding.getValue() );
|
|
||||||
assertTrue( idAttributeBinding.getValue() instanceof Column );
|
|
||||||
|
|
||||||
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
|
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" );
|
||||||
assertNotNull( nameBinding );
|
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
|
||||||
assertNotNull( nameBinding.getAttribute() );
|
return metadata.getEntityBinding( SimpleVersionedEntity.class.getName() );
|
||||||
assertNotNull( nameBinding.getValue() );
|
|
||||||
}
|
|
||||||
{
|
|
||||||
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml" );
|
|
||||||
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
|
|
||||||
EntityBinding entityBinding = metadata.getEntityBinding( SimpleVersionedEntity.class.getName() );
|
|
||||||
assertNotNull( entityBinding );
|
|
||||||
assertNotNull( entityBinding.getEntityIdentifier() );
|
|
||||||
assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() );
|
|
||||||
assertNotNull( entityBinding.getVersioningValueBinding() );
|
|
||||||
assertNotNull( entityBinding.getVersioningValueBinding().getAttribute() );
|
|
||||||
|
|
||||||
AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" );
|
|
||||||
assertNotNull( idAttributeBinding );
|
|
||||||
assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() );
|
|
||||||
assertNotNull( idAttributeBinding.getAttribute() );
|
|
||||||
assertNotNull( idAttributeBinding.getValue() );
|
|
||||||
assertTrue( idAttributeBinding.getValue() instanceof Column );
|
|
||||||
|
|
||||||
AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" );
|
|
||||||
assertNotNull( nameBinding );
|
|
||||||
assertNotNull( nameBinding.getAttribute() );
|
|
||||||
assertNotNull( nameBinding.getValue() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private XmlDocument readResource(final String name) {
|
private XmlDocument readResource(final String name) {
|
||||||
final String path = "/org/hibernate/test/id/Car.hbm.xml";
|
|
||||||
Origin origin = new Origin() {
|
Origin origin = new Origin() {
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
|
|
|
@ -23,10 +23,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.binding;
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@Entity
|
||||||
public class SimpleEntity {
|
public class SimpleEntity {
|
||||||
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class SimpleEntitySubClass extends SimpleEntity {
|
||||||
|
|
||||||
|
public SimpleEntitySubClass() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,8 @@ package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.metamodel.domain.Entity;
|
import org.hibernate.metamodel.domain.Entity;
|
||||||
import org.hibernate.metamodel.domain.SingularAttribute;
|
import org.hibernate.metamodel.domain.SingularAttribute;
|
||||||
import org.hibernate.metamodel.relational.Column;
|
import org.hibernate.metamodel.relational.Column;
|
||||||
|
@ -32,9 +34,6 @@ import org.hibernate.metamodel.relational.Datatype;
|
||||||
import org.hibernate.metamodel.relational.Schema;
|
import org.hibernate.metamodel.relational.Schema;
|
||||||
import org.hibernate.metamodel.relational.Size;
|
import org.hibernate.metamodel.relational.Size;
|
||||||
import org.hibernate.metamodel.relational.Table;
|
import org.hibernate.metamodel.relational.Table;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
package org.hibernate.metamodel.binding;
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO : javadoc
|
||||||
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SimpleVersionedEntity {
|
public class SimpleVersionedEntity {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
@GenericGenerator(name = "myGenerator", strategy = "sequence")
|
||||||
|
package org.hibernate.metamodel.binding;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.GenericGenerator;
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class OrmXmlParserTests extends BaseUnitTestCase {
|
||||||
|
@Test
|
||||||
|
public void testSingleOrmXml() {
|
||||||
|
OrmXmlParser parser = new OrmXmlParser();
|
||||||
|
Set<String> xmlFiles = new HashSet<String>();
|
||||||
|
xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm.xml" );
|
||||||
|
parser.parseAndUpdateIndex( xmlFiles, null );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
version="2.0">
|
||||||
|
<package>org.hibernate.test.annotations.onetoone</package>
|
||||||
|
<entity class="Father">
|
||||||
|
<attributes>
|
||||||
|
<id name="id">
|
||||||
|
<generated-value strategy="AUTO"/>
|
||||||
|
</id>
|
||||||
|
<basic name="name"/>
|
||||||
|
</attributes>
|
||||||
|
</entity>
|
||||||
|
<entity class="Son">
|
||||||
|
<attributes>
|
||||||
|
<id name="id">
|
||||||
|
<generated-value strategy="AUTO"/>
|
||||||
|
</id>
|
||||||
|
<basic name="name"/>
|
||||||
|
<one-to-one name="father">
|
||||||
|
<join-table name="father_son">
|
||||||
|
<join-column name="foo"/>
|
||||||
|
<inverse-join-column name="bar"/>
|
||||||
|
</join-table>
|
||||||
|
</one-to-one>
|
||||||
|
</attributes>
|
||||||
|
</entity>
|
||||||
|
</entity-mappings>
|
Loading…
Reference in New Issue