I'm developing a web application using Spring MVC/Security/JPA/Hibernate.
I have a User class which have OneToMany relation with UserRole.
@Entity
@Table(name = "user_accounts")
@SuppressWarnings("serial")
public class User extends SimpleBaseEntity<Long> implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "email", length = 100, nullable = false, unique = true)
private String email;
@Column(name = "first_name", length = 100,nullable = false)
private String firstName;
@Column(name = "last_name", length = 100, nullable = false)
private String lastName;
@Column(name = "password", length = 255)
private String password;
@OneToMany(fetch = FetchType.EAGER, cascade={CascadeType.ALL}, mappedBy="user")
@NotFound(action=NotFoundAction.IGNORE)
private List<UserRole> roles;
@Enumerated(EnumType.STRING)
@Column(name = "sign_in_provider", length = 20)
private SocialMediaService signInProvider;
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "user_image", length=16777216)
private byte[] userImage;
... skip
}
And the UserRole class has ManyToOne relation with User.
@Entity
@Table(name = "user_roles")
@SuppressWarnings("serial")
public class UserRole implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false, unique = true)
private Long id;
@Column(name = "user_id", length = 100, nullable = true)
private String userId;
@Enumerated(EnumType.STRING)
@Column(name = "role", length = 20, nullable = false)
private Role role;
@ManyToOne
@JoinColumn(name="user_id", referencedColumnName="email", insertable=false, updatable=false, nullable=false)
@NotFound(action=NotFoundAction.IGNORE)
private User user;
... skip
}
The User Repository interface is very simple.
public interface UserRepository extends JpaRepository<User, Long> {
public User findByEmail(String email);
}
When I load user information using repository using a code snippet below, it retrieves User and UserRole data finely.
User user = userRepository.findByEmail("some@email.com"); // OK both User and UserRole
Here is the log file.
Hibernate:
select
user0_.id as id1_9_,
user0_.creation_time as creation2_9_,
user0_.modification_time as modifica3_9_,
user0_.email as email4_9_,
user0_.first_name as first_na5_9_,
user0_.last_name as last_nam6_9_,
user0_.password as password7_9_,
user0_.sign_in_provider as sign_in_8_9_,
user0_.user_image as user_ima9_9_
from
user_accounts user0_
where
user0_.email=?
Hibernate:
select
roles0_.user_id as user_id3_9_1_,
roles0_.id as id1_10_1_,
roles0_.id as id1_10_0_,
roles0_.role as role2_10_0_,
roles0_.user_id as user_id3_10_0_
from
user_roles roles0_
where
roles0_.user_id=?
Hibernate:
select
user0_.id as id1_9_1_,
user0_.creation_time as creation2_9_1_,
user0_.modification_time as modifica3_9_1_,
user0_.email as email4_9_1_,
user0_.first_name as first_na5_9_1_,
user0_.last_name as last_nam6_9_1_,
user0_.password as password7_9_1_,
user0_.sign_in_provider as sign_in_8_9_1_,
user0_.user_image as user_ima9_9_1_,
roles1_.user_id as user_id3_9_3_,
roles1_.id as id1_10_3_,
roles1_.id as id1_10_0_,
roles1_.role as role2_10_0_,
roles1_.user_id as user_id3_10_0_
from
user_accounts user0_
left outer join
user_roles roles1_
on user0_.email=roles1_.user_id
where
user0_.email=?
However, here is the problem.
If I update User information in a service class using save(merge) method of the UserRepository, the same findByEmail method DOES NOT retrieve UserRole(roles) information but only User information.
User oldUser = userRepository.findByEmail("some@email.com"); // OK both User and UserRole(roles)
// ... some modifications of "oldUser"
userService.updateUser(oldUser); // This is Transactional and the table record is updated OK.
User newUser = userRepository.findByEmail("some@email.com"); // UserRole(roles) data is null
The hibernate log file is below.
# findByEmail oldUser
Hibernate:
select
user0_.id as id1_9_,
user0_.creation_time as creation2_9_,
user0_.modification_time as modifica3_9_,
user0_.email as email4_9_,
user0_.first_name as first_na5_9_,
user0_.last_name as last_nam6_9_,
user0_.password as password7_9_,
user0_.sign_in_provider as sign_in_8_9_,
user0_.user_image as user_ima9_9_
from
user_accounts user0_
where
user0_.email=?
Hibernate:
select
roles0_.user_id as user_id3_9_1_,
roles0_.id as id1_10_1_,
roles0_.id as id1_10_0_,
roles0_.role as role2_10_0_,
roles0_.user_id as user_id3_10_0_
from
user_roles roles0_
where
roles0_.user_id=?
Hibernate:
select
user0_.id as id1_9_1_,
user0_.creation_time as creation2_9_1_,
user0_.modification_time as modifica3_9_1_,
user0_.email as email4_9_1_,
user0_.first_name as first_na5_9_1_,
user0_.last_name as last_nam6_9_1_,
user0_.password as password7_9_1_,
user0_.sign_in_provider as sign_in_8_9_1_,
user0_.user_image as user_ima9_9_1_,
roles1_.user_id as user_id3_9_3_,
roles1_.id as id1_10_3_,
roles1_.id as id1_10_0_,
roles1_.role as role2_10_0_,
roles1_.user_id as user_id3_10_0_
from
user_accounts user0_
left outer join
user_roles roles1_
on user0_.email=roles1_.user_id
where
user0_.email=?
# Update User
update
user_accounts
set
modification_time=?,
email=?,
first_name=?,
last_name=?,
password=?,
sign_in_provider=?,
user_image=?
where
id=?
# findByEmail newUser
Hibernate:
select
user0_.id as id1_9_,
user0_.creation_time as creation2_9_,
user0_.modification_time as modifica3_9_,
user0_.email as email4_9_,
user0_.first_name as first_na5_9_,
user0_.last_name as last_nam6_9_,
user0_.password as password7_9_,
user0_.sign_in_provider as sign_in_8_9_,
user0_.user_image as user_ima9_9_
from
user_accounts user0_
where
user0_.email=?
Is there anyone can help me?
Thanks in advance.