-->
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.  [ 4 posts ] 
Author Message
 Post subject: Move to annotations (frm xdclet) changes query semantics
PostPosted: Fri Mar 07, 2008 12:39 pm 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
We changed a mapping from XDoclet/.hbm to Annotations and our initial login query no longer works. No bags are in use, but we are getting multiple Users for a userID. It is a ManyToMany with a join table.

The query is a criterion query to get all Users with userID and password equal to specified values.

Under XDoclet everythign works fine, but when mapped using Annotations, it exhibits duplicate record behavior.

Does the mapping technique (.hbm vs annotatiosn) change the query semantics? We need our existing, mature system to continue to function without re-working all the queries, so we may need to abandon our effor if they are substantially different in semantics.

We are familiar with the outer-join issues in HQL that can cause this, but did not expect that merely changing the mapping syntax would alter semantics. Can any explain what is happening?


Hibernate version:
3.2.5 core + 3.3.0 annotations

Mapping documents (I've left in the old XDoclet for reference purposes)
Code:
@Entity
@Table(name="user")
@Proxy(lazy=false)
public class User {

/**
     *            @hibernate.set
     *             name="roles"
     *             table="user_has_role"
     *                lazy="false"
     *                cascade="save-update"
     *            @hibernate.collection-key
     *                column="user_guid"
     *            @hibernate.collection-many-to-many
     *                class="com.app.Role"
     *             column="role_guid"
     */
    @ManyToMany(fetch=FetchType.EAGER, targetEntity=com.app.Role.class)
    @Cascade({CascadeType.SAVE_UPDATE})
    @JoinTable(name="user_has_role",
    joinColumns={@JoinColumn(name="user_guid")},
    inverseJoinColumns={@JoinColumn(name="role_guid")})
    public Set getRoles() {...


@Entity
@Table(name="role")
@Proxy(lazy=false)
public class Role {
    @Basic
    @Column(name="Role", nullable=false)
    public String getName() {
        return this.name;
    }



The generated SQL (show_sql=true):
Code:
    [exec] 22:45:06,765 INFO  [STDOUT] Hibernate:
select this_.user_guid as user1_65_1_, this_.isActive as isActive65_1_, this_.Password as Password65_1_, this_.UserID as UserID65_1_,
roles2_.user_guid as user1_3_, role3_.role_guid as role2_3_, role3_.role_guid as role1_57_0_
from
   user this_
   left outer join user_has_role roles2_ on this_.user_guid=roles2_.user_guid
   left outer join role role3_ on roles2_.role_guid=role3_.role_guid where (this_.UserID=? and this_.Password=?)


Top
 Profile  
 
 Post subject: Any help?
PostPosted: Mon Mar 10, 2008 9:51 am 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
We are still stumped on this. It works to put all the results into a Set to remove duplicates (and saw Emmanuel's recent reference to the DISTINCT_ROOT_ENTITY transformer), and I can now get a unique user for login; however, this change in the results of a query scares us all, since we have a large, mature system and expected the annotations upgrade to simply be a matter of "finding" the right annotations to replace our XDoclet tags.

Instead, this subtle change in query behavior arose, and we can't explain it.

I'm sure many people are working on migration from .xbm/XDoclet to annotations and need to know any gotchas or tricks.

Please Help!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 10, 2008 7:25 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
AFAIK Hibernate has always behaved like that. But you don't show the query nor the version of Hibernate you're moving to.

anyway, from what I can read, this is the expected behavior.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Found the issue - related to fetch=FetchMode vs @Fetch tag
PostPosted: Tue Mar 11, 2008 10:44 pm 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
We found the problem - it was that we misunderstood the eager/lazy annotations. We changed mappings with lazy="true" to annotations with fetch=FetchType.LAZY, and lazy="false" to FetchType.EAGER. However EAGER and LAZY have a dual meaning in annotations, since they also specify the outer-join behavior. Instead (depending on some other settings) we use the two annoations:

@Fetch(FetchMode.SELECT)
@LazyCollection(LazyCollectionOption.FALSE)

To force eager loading without triggering outer joins. The outer join changes query semantics, as noted in the docs and at least one FAQ on the hibernate site.


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