-->
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.  [ 3 posts ] 
Author Message
 Post subject: Can't force popluation of manyToMany collection using join
PostPosted: Mon Nov 03, 2008 1:05 pm 
Newbie

Joined: Sat Nov 01, 2008 3:58 pm
Posts: 7
I have a JPA entity with a manyToMany relationship defined. If I set the fetch type to eager for the collection or if I keep it lazy and make a call to get the collection, the collection populates just fine.

The problem is I want to force the population of this collection using a join in my query, but whenever I do that, I get an error like:

javax.persistence.NonUniqueResultException: result returns 4 elements

I'm not sure why this is happening. The 4 elements is based off the size of the collection, but why it's not forcing it to be loaded into collection has me stumped. I'm a newb so I'm sure it's something stupid I'm missing.

Posting some relevant code below:



Code:
@Entity
@Table(name = "Attribute")
@NamedQueries({
    @NamedQuery(name = "Attribute.findByAttributeID", query = "SELECT a FROM Attribute a left join fetch a.attributeValues  WHERE a.attributeID = :attributeID order by a.attributeID",
         hints = {
          @QueryHint(name = "org.hibernate.flushMode", value = "manual"),
          @QueryHint(name = "org.hibernate.readOnly", value = "true")
         })
})
public class Attribute implements Serializable {
   //...
   @JoinTable(name = "AttributeAttributeValue",
        joinColumns = {@JoinColumn(name = "attributeID", referencedColumnName = "attributeID")},
        inverseJoinColumns = {@JoinColumn(name = "attributeValueID", referencedColumnName = "attributeValueID")})
    @ManyToMany
    private Collection<AttributeValue> attributeValues;

   //get/setter

}

public class AttributeValue implements Serializable {
    @ManyToMany(mappedBy = "attributeValues")
    private Collection<Attribute> attributes;
}


//in a test case:
Attribute a = (Attribute) em.createNamedQuery("Attribute.findByAttributeID").setParameter("attributeID", 1424).getSingleResult();


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 03, 2008 4:06 pm 
Newbie

Joined: Sat Nov 01, 2008 3:58 pm
Posts: 7
This is driving me mad. Now I'm even more stumped. It's not just ManyToMany but even OneToMany where I have FetchType set to LAZY and then I try to force the collection to be populated with "join fetch."

I thought the problem might have been that I wasn't using a Set as my data type but I changed the data type from Collection to Set and I'm still seeing the problem.

There has to be something else going on, I just don't get it. If I set the products field to eager fetched, I'll end up with just ONE ProductGroup returned and my Set of products. When I set it to lazy and try to force it being fetched, I end up with 27 ProdutGroups returned (the number of products returned.)

I suppose I could just get the List back and then use the first one in the List, but that seems sort of messed up. What am I doing wrong...

Code:
@Entity
@Table(name = "NPPProductGroup")
@NamedQueries({
    @NamedQuery(name = "ProductGroup.findByProductGroupID",
    query = "SELECT p FROM ProductGroup p left join fetch p.products WHERE p.productGroupID = :productGroupID")
})
public class ProductGroup implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "productGroupID", nullable = false)
    private Integer productGroupID;
   
   //columns and set/gets removed

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productGroup", fetch=FetchType.LAZY)
    private Set<Product> products;
}


@Entity
@Table(name = "NPPProduct")
public class Product implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "productID", nullable = false)
    private Integer productID;

    //cols get sets removed

    @JoinColumn(name = "productGroupID", referencedColumnName = "productGroupID")
    @ManyToOne(fetch=FetchType.LAZY)
    private ProductGroup productGroup;

}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 03, 2008 5:21 pm 
Newbie

Joined: Sat Nov 01, 2008 3:58 pm
Posts: 7
Is the only solution to do this:

Code:
List<ProductGroup> pgs = em.createNamedQuery("ProductGroup.findByProductGroupID").setParameter("productGroupID", 1).getResultList();
        ProductGroup pg = pgs.get(0);


which works. Just seems awkward. You might originally have a dao method that calls getSingleResult() and then you later add a join fetch and you have to back and modify your dao.


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