I have an entity which references a list of type enum. The list is stored in the database as following:
userName role
-----------------------
user0001 role1
user0001 role2
user0001 role3
user0002 role1
The corresponding java class is roughly like this:
@Entity
@Table(name = "UserTable")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "userId")
private Integer id;
@Column(name = "user_name")
private String userName;
@ElementCollection(targetClass = Role.class)
@CollectionTable(name = "User_Roles")
@Column(name = "role")
@Enumerated(EnumType.STRING)
private List<Role> roles;
}
I checked this and this question for the mapping. Yet I have two issues. First issue is that the userName
is not the PK in my UserTable
and as far as I know, hibernate does join on the PK.
The second issue is this error with the current setup:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.project.Common.User.roles, could not initialize proxy - no Session
This error shall be fixed by EAGER
loading, but as I tried that one, I got the following error at startup:
java.lang.IllegalStateException: Attempt to register multiple SQL table aliases [roles1_, roles2_, etc] against query space uid [< gen:1>]
What do I need to change in order for this mapping to work?
Please note that I wouldn't like to perform any database changes if that is in any way possible.
Also I do think that I would actually have to go with FetchType.EAGER
, as I for now only query the database once and would need to get roles as well for later usage. Of course I could also change the way my application handles this and query the roles again when I need them explicitly, tho I am not sure if that way would be better.
Alright, I found a not so nice workaround. First of all, I annotated the List<Role> roles;
as following:
@ElementCollection(targetClass = Role.class)
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "userName"))
@Enumerated(EnumType.STRING)
@Column(name = "role")
private List<Role> roles;
My Role
enum does not have any annotations.
This setup would normally result in the LazyInitializationException
, which I worked around by adding a System.out.println(user);
as this does access the roles
list (replacing it with a getRoles()
resulted in the same exception) directly after fetching the user.
As you can guess, this solution is not really fine/acceptible at all. As long as I don't find a better solution (most probably eager-loading), I will roll with this one.
UPDATE
I actually got it solved. It works now with eager-loading
. In fact, the setup remained as posted above in the answer. The IllegalStateException
I mentioned in the question, is actually caused by the bug HHH-12594. I simply removed hibernate.default_batch_fetch_size
from my configuration and it then worked as intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With