-->
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.  [ 7 posts ] 
Author Message
 Post subject: different behaviour in new session
PostPosted: Wed Jul 05, 2006 5:09 pm 
Newbie

Joined: Wed Jul 05, 2006 1:47 pm
Posts: 6
Location: Belgium
hi,

I'm getting very strange behaviour (using 3.1.3, but even with the most current version: 3.2.0.cr2) and I hope there's something obvious I've missed

summary:
    * adding/removing mappings for POJOs that are never even used makes Hibernate throw an exception
    * executing the exact same finder (after just having created some entities) in a different session makes Hibernate throw an exception

I'm a bit reluctant to post all my mappings and code because it would make this post very long; anyway I'll try to describe the problem and perhaps someone out there has had a similar problem

object model:
    * 3 separate hierarchies of union-subclass inheritance
    * hierarchies share a few relationships
    * all POJOs are immutable Java classes, member fields are private
    * using Java5 generics on associations
    * hsqldb in-memory (the problem arises during unit testing), hibernate.hbm2ddl.auto=create-drop; using the HSQLDB dialect

mappings:

execution A (works fine):
    * configure programmatically
    * build sessionfactory
    * open session
    * start transaction
    * create a few objects
    * commit transaction
    * try to find objects
    * close session

this works fine as expected, however (notice a and b):

execution B (throws exception, different finder query in step 7):
    * configure programmatically
    * build sessionfactory
    * open session
    * start transaction
    * create a few objects
    * commit transaction
    * a. close session
    * b. open new session
    * try to find objects
    * close session

this yields a problem during the finder where the exception says:
org.hibernate.PropertyAccessException: could not set a field value by reflection setter of ntc.nms.framework.configuration.SimpleManagedObject.invalid

('invalid' is a primitive boolean property, which is mapped with not-null="true", also note that my schema is dropped-created on each run so there's nothing left from a previous run)

I've traced this problem down to a certain SQL query which contains the following fragment: ..., null as INVALID, null as ALGORITHM, ID, null ... (actual query is very long, I've just pasted the relevant portion)

as far as I understand this is the union-subclass mapping doing a table scan using 'union' in order to find the specific object instances matching my query (I'm trying to find objects which match a value from a set of identifiers)

now the problem is that the query succeeds fine, but when 'hydrating' the POJO Hibernate attemps to set 'null' into a primitive field, even though that field has explicitely been set to not-null="true", and while doing so an exception occurs since this is something which cannot be done

execution C (works fine too):

when I remove all mappings, except the ones for the classes being used, then it works too

execution D (works fine too):

if all my relationships are fetched lazily then it also works, I've not tested this extensively since working this way isn't an option and I'm running out of time :-/

questions:

    * can someone explain to me why a finder would behave this way in a different session ?
    * why is the SQL query different ? remember, execution A works fine!
    * why would a working query be broken by adding a single mapping which would never be used (mapping could even contain no properties or associations, just the POJO name)


I would really want to understand what's going on here ..
thanks in advance!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 05, 2006 6:24 pm 
Newbie

Joined: Wed Jul 05, 2006 1:47 pm
Posts: 6
Location: Belgium
I cannot reproduce the problem when I replace union-subclass with joined-subclass

considering both strategies are more or less equivalent I find it strange the former would yield such exception

would this behaviour be considered a bug or is it possible I mapped something which violates certain Hibernate constraints (I'm not doing anything special though) ?

_________________
wouter [at] andromda [dot] org


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 05, 2006 6:32 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
not-null="true" on a primitive field is used only during database creation. It has no effect on what hibernate does when loading a null DB value into a POJO property. If null is possible (and it frequently is when working with unions) then you should change the java types to be the wrapper class (change int to Integer, etc.).

union-subclass and join-subclass are decidedly not equivalent. Hibernate makes them look fairly similar on the java side, but they are very different.

What do you mean by "finder" in your post? If you mean a Query object, then you will have a problem if you create the Query object using session A, then try to use it when session A is closed and session B is open. If that's what you're doing, you should change to either creating the Query using session B, or creating a DetachedQuery, and attaching it to session B in order to run it.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 05, 2006 7:52 pm 
Newbie

Joined: Wed Jul 05, 2006 1:47 pm
Posts: 6
Location: Belgium
hi, thanks for your quick answer,

using wrapper classes effectively stores null into the field, but this is not something I want to see (since it has been flagged not-null for a reason), as a matter of fact, I'm using primitives to enforce a non-null value :-)

about the union vs. joined strategies, are you talking about the way Hibernate will build the underlying schema (I understand that part) or are there some things I should be aware of, specific query side effects or things I should avoid doing ? (I couldn't find anything related in the best-practices section or faqs); what I'm basically asking is: will switching between union/joined strategies mean I would have to be updating other parts of mapping documents too ?

I noticed joined vs. subclass having a slight difference in the limitations matrix for the "Polymorphic one-to-many" column, that's why I mentioned I was implementing this association type with a many2many having a uniqueness constraint on one column: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#inheritance-limitations

the finder was actually a findById(Long), I have implemented this logic using several alternatives:

1. Session.load(MyEntity.class, 1L)
2. Session.createQuery("from " + MyEntity.class.getName() + " where id=1")
3. Session.createQuery("from " + MyEntity.class.getName() + " where id in (1,2,3)")
4. using the criteria API

I never used any object reference (such as Query) from a closed Session, the finder logic was executed with a new Session (B) instance and that part of the code could not see anything from Session A

_________________
wouter [at] andromda [dot] org


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 05, 2006 8:15 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
The difference between union and joined subclassing is in the way polymorphic queries work. joined-subclass is usually better, but only works when the superclass maps to a table: union-subclass works when the superclass is not mapped to a table.

I don't know if we need to explore that too much, because the problem is in your finders. You seem to be using the subclasses in the query: you should be using the superclass. That is, the from clause shouldn't be generated at query time, and doing that is causing your problems. Change
Code:
Session.createQuery("from " + MyEntity.class.getName() + " where id in (1,2,3)")
to
Code:
Session.createQuery("from SuperClassImpl where id in (1,2,3)")
This is why they're called polymorphic queries. Note that even if you know the class of the result in advance, you don't have to tell hibernate: your mapping has given hibernate enough info to figure out the real class when the result set is being parsed.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 2:58 am 
Newbie

Joined: Wed Jul 05, 2006 1:47 pm
Posts: 6
Location: Belgium
I would think union-subclass to be more performant in general, is that correct (I'm asking since you mentioned a preference for joined-subclass) ?

yeah MyEntity was the supertype, it's called Top in my application; I'll be more concrete, I have (this is based on TMN ITU-T X.721):

hierarchy1: SimpleManagedObject --> Top

and

hierarchy2: AttributeValueChangeRecord --> EventLogRecord --> LogRecord

hierarchy3: AttributeValueChange

relations: AttributeValueChangeRecord [1] ---> [0..*] AttributeValueChange (lazy="false")

when searching by ID I always target the root of the inheritance hierarchy in which to perform the search (it wouldn't make much sense otherwise, this is what you meant, right?).

(note that I use this root type in all possible finder alternatives such as Session.load(..) etc...)

I'm really puzzled by the fact it works when I do everything in a single session or when I switch to joined-subclass, the behaviour is very counter-intuitive because from the reference docs I get the impression that there are no specific requirements when using either strategy

and get this: when I simply do not add mappings that have no relation with any of the existing mappings (and these newly added ones may even represent empty entities: no properties or associations) then it works fine, even when doing stuff in the new session or in whatever situation that used to fail
ps: I'm never mixing strategies, I'm trying to keep it simple

_________________
wouter [at] andromda [dot] org


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 06, 2006 5:40 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
Very weird. I don't have an explanation for that. Is it possible that there's a bug in your joined-subclass code or mapping that you haven't noticed and isn't in the alternatives?

joined-subclass might be a little slower than union-subclass for very large tables, but with appropriate indices the difference in performance should not be noticeable. I suppose it depends on how your DBMS optimizes things: two simple selects is probably faster that one joined select, but maybe not.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 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.