2

I have the following two fields in a Hibernate managed entity:

@ElementCollection(targetClass = PersonAttributes.class, fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name = "PERSON_ATTRIBUTES", joinColumns = { @JoinColumn(name = "PERSON_ID") })
@Column(name = "ATTRIBUTES")
private List<PersonAttributes> attributes;

@ElementCollection(targetClass = PersonRoles.class, fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@CollectionTable(name = "PERSON_ROLES", joinColumns = { @JoinColumn(name = "PERSON_ID") })
@Column(name = "ROLES")
private List<PersonRoles> roles;

When I choose two PersonAttributes values and two PersonRoles values and persist the entity, on reading it from the database, the values are cross-multiplized.

Example:

Persisting roles=[ADMIN, SUPERVISOR] and attributes=[ATTRIBUTE1, ATTRIBUTE2]. On reading the entity from Database I get roles=[ADMIN, SUPERVISOR, ADMIN, SUPERVISOR] and attributes=[ATTRIBUTE1, ATTRIBUTE1, ATTRIBUTE2, ATTRIBUTE2].

Another Example:

Persisting roles=[ADMIN] and attributes=[ATTRIBUTE1, ATTRIBUTE2]. On reading the entity from Database I get roles=[ADMIN, ADMIN] and attributes=[ATTRIBUTE1, ATTRIBUTE2].

Looks there is some unexpected joining? How can I get Hibernate reading the persisted enumerations without this cross-multiplication?

Additional information: This occurs when I use the entityManager.find() method. But when I get all entities as list via JPQL SELECT Statement, the enumerations are appropriate.

sanluck
  • 1,544
  • 1
  • 12
  • 22
Alex Andersen
  • 127
  • 1
  • 1
  • 14
  • so look at what is persisted and the SQL invoked to persist it, and then look at the SQL invoked to retrieve the fields. – Neil Stockton Mar 29 '16 at 07:11

1 Answers1

1

Look at this answer please @OneToMany List<> vs Set<> difference.

You can't retrieve more than one java.util.List in entity. Use java.util.Set instead of List if you want attach more than one Collection to your entity.

Community
  • 1
  • 1
sanluck
  • 1,544
  • 1
  • 12
  • 22
  • In JPA a class can __have__ more than one List field. JPA is there to persist the users class, not to impose arbitrary restrictions on what fields the user can or can't have. The link says that __Hibernate__ cannot retrieve more than 1 List in one call. The key word there is _retrieve_ not _use_ – Neil Stockton Mar 29 '16 at 07:00
  • Neil, you said right, I expressed incorrectly this situation. I've changed the answer. – sanluck Mar 29 '16 at 07:08
  • Ok, but that doesn't fix the users issue. Just because Hibernate cannot reliably retrieve 2 Lists in one SQL doesn't mean that Hibernate should attempt to retrieve 2 Lists in one SQL. If it knows it can't do it then it should retrieve in 2 SQL statements. The user should always get the data they have persisted. If they don't then that is a Hibernate bug. Is it a Hibernate bug ? – Neil Stockton Mar 29 '16 at 07:19
  • Yes, it's a bug. This bug fixed in Hibernate 5. Let me found the issue in Hibernate tracker.. – sanluck Mar 29 '16 at 07:22
  • Fixed in [this issue](https://hibernate.atlassian.net/browse/HHH-5855). Also there are workarounds : >This problem can be worked around by: > Changing the OneToMany relationship from a List to a Set > Only using either Cascade MERGE or PERSIST not both of ALL > Add a new B to A.getBs by adding to the '0' index (a.getBs.add(0,new B())) – sanluck Mar 29 '16 at 07:26
  • Thanks! Using java.util.Set fixed this. – Alex Andersen Apr 21 '16 at 19:53