0

I have a one to many relationship on a bunch of my entities. However I do not always want to have a value defined for the children. Since it can be a one to many it could be null.

When I do not create the child object my tests fail with a Referential integrity constraint violation.

I tried adding nullable true to the join however that did not seem to resolve the issue.

@JoinColumn(name = "image_relation")
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany
private List<Image> productImageGroup;

I tried using fetch type of eager and got a different error.

@JoinColumn(name = "product_item_relation")
@OneToMany(fetch=FetchType.EAGER)
private List<ProductItems> productItemGroup;

Throws:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
zmanc
  • 5,201
  • 12
  • 45
  • 90
  • 2
    This is most likely related to LazyCollection, there is normally no problem having null onetomany relations. – Rasmus Franke Mar 27 '13 at 12:56
  • Before I started doing LazyCollection I had fetch type of eager, then when I added a second onetomany I ran into a too many bags issue. – zmanc Mar 27 '13 at 13:57
  • Have you looked at http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags? – sharakan Mar 27 '13 at 14:06
  • @sharakan, yes that is why i switched to Lazy, and started getting the other issue. – zmanc Mar 27 '13 at 14:12
  • "The other issue" being the referential integrity one? Can you add the stack trace of that? – sharakan Mar 27 '13 at 14:14
  • 1
    I don't think adding LazyCollection is the standard solution to the multiple bag problem. Can you use a Set? Fetching multiple sets is allowed. Even if you need lists in some cases, you can easily convert to whatever you need within getters. – Rasmus Franke Mar 27 '13 at 14:18
  • @RasmusFranke, please add that as the answer so I can give you credit. – zmanc Mar 27 '13 at 15:09

1 Answers1

1

the problem is most likely related to @LazyCollection being missused.

Multiple bag exceptions are throwed when more than a single List is eager fetched. You can solve this in two ways:

Replace the list with a set. Any number of Sets are allowed to be eagerly fetched.

@JoinColumn(name = "product_item_relation")
@OneToMany(fetch=FetchType.EAGER)
private Set<ProductItems> productItemGroup;

Or remove eager fetching and handle this in your program code

@JoinColumn(name = "product_item_relation")
@OneToMany
private List<ProductItems> productItemGroup;

public List<MyObject> getMyObjects(){
    List<MyObject> objects = entityManager.createQuery("SELECT o FROM MyObject o").getResultList();
    // OneToMany not fetched yet
    for(MyObject o : objects)
        Hibernate.initialize(o.getProductItemGroup()); // Same as simply accessing the list to force loading, but states your intention more clearly.
    // OneToMany collection is now fetched.
    return objects;
}

You can improve the performance of this greatly by specifying @org.hibernate.annotations.Fetch(fetchMode) on the collection and specifying subselect or join. Note that this is a hibernate specific annotation and your application will no longer be free of vendor dependancy

Rasmus Franke
  • 4,434
  • 8
  • 45
  • 62