-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Mappings in orm.xml not getting processed
PostPosted: Tue Feb 13, 2007 12:52 am 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
Hibernate version:
core: 3.2.2, annotations: 3.2.1GA, entity-manager: 3.2.1GA

Here's the scenario:

Code:
public class A implements Serializable {
   protected int id;
   protected String name;
   ...
}

public class B extends A {
   ...
}


In orm.xml
Code:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="1.0">
    <access>FIELD</access>
    <entity name="B" class="some.package.B">
        <table name="TABLE_B"/>
        <attributes>
            <id name="id">
                <column name="B_ID"/>
            </id>
            <basic name="name"/>
        </attributes>
    </entity>
<entity-mappings/>


HBM annotations fail to process attributes in B, and eventually complains that entity B has no primary key.

Exact error message is as follows:
Code:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/sf-context2.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity: some.package.B
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: some.package.B
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:627)
        at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:452)
...


cont. next post.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 13, 2007 1:21 am 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
After a rather tedious debugging session, I've isolated the problem to org.hibernate.reflection.java.JavaXClass.getDeclaredFieldProperties(...) method.

Code:
   private List<XProperty> getDeclaredFieldProperties(Filter filter) {
      List<XProperty> result = new LinkedList<XProperty>();
            for ( Field f : toClass().getDeclaredFields() ) {
                if ( JavaXProperty.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ), filter ) ) {
                    result.add( getFactory().getXProperty( f, this ) );
                }
            }
        return result;
   }



Obviously toClass().getDeclaredFields() called on class B do not return fields declared in class A, so respective field mappings in orm.xml are ignored.

So, I've changed the code (same with getDeclaredMethodProperties) to lookup superclass defined fields too:

Code:
   private List<XProperty> getDeclaredFieldProperties(Filter filter) {
      List<XProperty> result = new LinkedList<XProperty>();
        Class clazz = toClass ();
        while (null != clazz) {
            for ( Field f : clazz.getDeclaredFields() ) {
                if ( JavaXProperty.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ), filter ) ) {
                    result.add( getFactory().getXProperty( f, this ) );
                }
            }
            clazz = clazz.getSuperclass ();
        }
        return result;
   }


That fixed the immediate problem, but another one cropped up:

In org.hibernate.reflection.java.EJB3OverridenAnnotationReader constructor, classname is set with the following:

Code:
...
   else if ( el instanceof Field ) {
   Field field = (Field) el;
   className = field.getDeclaringClass().getName();
...


Consequently initAnnotations() fail to locate the correct mapping since it's looking for
entity A.id in orm.xml, whereas it's defined as entity B.id.

I see no easy way to fix this. It's possible to propagate the correct entity class in context to AnnotationReader, but it's rather convoluted and possibly break other things if (I) attempted.

This mapping worked fine under Toplink Essentials, and as far as I've seen the jpa specification doesn't prohibit doing so (then again the spec is rather silent on many things).

So, what would be the best way to proceed? If there's a workaround, I'd be happy to hear it, though I'm rather reluctant to change the mappings since this pattern is repeated on a huge number of entities. I can submit a bug report and/or try to patch it myself and submit for your review, if you think that's a bug.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 13, 2007 3:29 am 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
I've worked my way around that by using mapped-superclass annotations on a sample mapping, however I can't get one-to-many relations working now:

Code:
org.hibernate.MappingException: Could not determine type for: java.util.Set, for columns: [org.hibernate.mapping.Column(references)]
   at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:266)
   at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
   ...


Following the previous example:

Code:
public class A implements Serializable {
   protected int id;
   protected String name;

   protected Set<C> references; 
   ...
}


Code:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="1.0">
    <mapped-superclass class="some.package.A" access="FIELD">
        <attributes>
            <id name="id">
                <column name="B_ID"/>
            </id>
            <basic name="name"/>
            <one-to-many name="attributes" target-entity="some.package.C"  mapped-by="owner"></one-to-many>
        </attributes>
    </mapped-superclass>
    ...
    <mapped-superclass class="some.package.C" access="FIELD">
        <attributes>
            ...
            <many-to-one name="owner">
                <join-column name="OWNER_ID" referenced-column-name="B_ID" insertable="false" updatable="false"/>
            </many-to-one>
        </attributes>
    </mapped-superclass>
    ...
<entity-mappings/>


Debugging into code, it seems A.references property passed to CollectionBinder.getCollectionBinder(...) has JavaXSimpleType as xType, which obviously is not a collection (property.type is correctly identified as java.util.Set<C>). Any ideas?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 15, 2007 7:30 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
The ORM filre needs to reflect the class structure, so yes mapping id has to be done on A even in orm.xml

Regarding your latest problem
Code:
protected Set<C> [b]references[/b]; 
<one-to-many name="[b]attributes[/b]" target-entity="some.package.C"  mapped-by="owner"></one-to-many>



not the same name...

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 16, 2007 5:19 am 
Newbie

Joined: Thu Jun 01, 2006 6:05 pm
Posts: 6
emmanuel wrote:
not the same name...


Bah you're right of course, it seems I copied the wrong line from the actual orm.xml, (which is rather lenghty to post here), it should read:

Code:
            <one-to-many name="references" target-entity="some.package.C" mapped-by="instId"></one-to-many>


So the problem remains. I'll try to work out a small test case and post it here.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.