JPA Join on specific field
You need to use referencedColumnName
:
@ManyToOne
@JoinColumn(name="username", referencedColumnName="username", nullable=false)
private User user;
With only @JoinColumn(name="username")
you tell Hibernate that the join column in user_roles
is named username
- but it still expects that it contains the values of the @Id
property of User. If you create the DDL for your schema you will see that Hibernate generates a number column for user_roles.username
.
Comments
-
s1moner3d over 1 year
I have this scenario:
User and his related UserRole entity classes, as below:
@Entity @Table(name="USER") public class User implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="ID", unique=true, nullable=false) private int id; @Column(name="USERNAME", unique=true, nullable=false, length=255) private String username; @OneToMany(mappedBy="user") private List<UserRole> userRoles; }
and
@Entity @Table(name="user_roles") public class UserRole implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="user_role_id", unique=true, nullable=false) private int userRoleId; @Column(nullable=false, length=45) private String role; @ManyToOne @JoinColumn(name="username", nullable=false) private User user; }
Now, I need to query all users that have a specific role. I'm trying making join with JPA Specifications, like that:
Join<User, UserRole> join = root.join(User_.userRoles); Expression<String> match = join.get(UserRole_.role); Predicate predicate = builder.equal(match, "ROLE_USER");
The problem is that the generated join will be between User.id and UserRole.username and the query will obviously have no results.
select count(user0_.ID) as col_0_0_ from USER user0_ inner join user_roles userroles1_ on user0_.ID=userroles1_.username where userroles1_.role='ROLE_USER'
I need instead to have the on clause both on username fields:
... from USER user0_ inner join user_roles userroles1_ on user0_.USERNAME=userroles1_.username ...
I noticed that there is the .on method of Join class who:
Modify the join to restrict the result according to the specified ON condition. Replaces the previous ON condition, if any. Return the join object
Is this the correct approach? If so, how could I implement that?
Join<User, UserRole> join = root.join(User_.userRoles).on(????);
Thank you in advance.
UPDATE:
UserRole_
metamodel class@StaticMetamodel(UserRole.class) public class UserRole_ { public static volatile SingularAttribute<UserRole, Integer> userRoleId; public static volatile SingularAttribute<UserRole, String> role; public static volatile SingularAttribute<UserRole, User> user; }
User_
metamodel class:@StaticMetamodel(User.class) public class User_ { public static volatile SingularAttribute<User, Integer> id; public static volatile SingularAttribute<User, String> username; public static volatile ListAttribute<User, UserRole> userRoles; }