I have the following 2 entities:
#Entity
public class User implements java.io.Serializable {
private Integer iduser;
private String email;
private String password;
private Byte enabled;
private Set<Token> tokens = new HashSet<>(0);
public User() {
}
public User(String email, String password, Byte enabled/*, Set groupRights*/, Set tokens) {
this.email = email;
this.password = password;
this.enabled = enabled;
this.tokens = tokens;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "iduser", unique = true, nullable = false)
public Integer getIduser() {
return this.iduser;
}
public void setIduser(Integer iduser) {
this.iduser = iduser;
}
#Column(name = "email", unique = true, length = 45)
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "password", length = 60)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "enabled")
public Byte getEnabled() {
return this.enabled;
}
public void setEnabled(Byte enabled) {
this.enabled = enabled;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Token> getTokens() {
return this.tokens;
}
public void setTokens(Set<Token> tokens) {
this.tokens = tokens;
}
}
#Entity
public class Token implements java.io.Serializable {
private String idtoken;
private User user;
private Date tokenTtl;
private String ipLock;
public Token() {
}
public Token(String idtoken) {
this.idtoken = idtoken;
}
public Token(String idtoken, User user, Date tokenTtl, String ipLock) {
this.idtoken = idtoken;
this.user = user;
this.tokenTtl = tokenTtl;
this.ipLock = ipLock;
}
#Id
#Column(name = "idtoken", unique = true, nullable = false, length = 36)
public String getIdtoken() {
return this.idtoken;
}
public void setIdtoken(String idtoken) {
this.idtoken = idtoken;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "token_ttl", length = 19)
public Date getTokenTtl() {
return this.tokenTtl;
}
public void setTokenTtl(Date tokenTtl) {
this.tokenTtl = tokenTtl;
}
#Column(name = "ip_lock", length = 45)
public String getIpLock() {
return this.ipLock;
}
public void setIpLock(String ipLock) {
this.ipLock = ipLock;
}
}
the problem is that when I select a user using this JPA-QL: select u from User u, I get a null Set related to Tokens, even though there are associated tokens for this user.
This problem arises only when I get the JPA context (EntityManager) in a Spring 4 context. If I'm doing a test, creating the EntityManager directly (using this: Persistence.createEntityManagerFactory("unit-name");), this issue is not present.
Can anybody tell me what's the cause of my issue?
You need to use in this way
private Set<Token> tokens = new HashSet<Token>(0);
Create the Getter Setter accordingley
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<Token> getTokens() {
return this.tokens;
}
public void setTokens(Set<Token>tokens) {
this.tokens = tokens;
}
The problem is related to a bug from OpenJPA.
When in OpenJPA you create a bidirectional #OneToMany relationship with FetchType.EAGER fetch type, the bug comes up by not being able to create this relation. The bug is fixed in some versions. Seems to affect versions 2.1.0, 2.2.2, 2.3.0 and 2.4.0.
References:
https://issues.apache.org/jira/browse/OPENJPA-2505
Spring Data JPA OneToMany and ManyToOne give me JpaSystemException
Related
I have tables User, Roles, Groups and a join table GroupRoles. A user can have many Roles (some of which are not group specific), and a Group can have many roles. Since Roles can be group related I need to associate a groupID with them and hence GroupRoles has a unique key of userID, groupID and roleID. I need userID as part of the key as I need to know what Roles are associated to a user. In hibernate is mapping a unique key like this the same as mapping a composite key, where I would have something along the lines of
#Embeddable
public class GroupRoleKey implements Serializable {
#Column(name="userID")
private Long userID;
#Column(name="groupID")
private Long groupID;
#Column(name="roleID")
private Long roleID;
protected GroupRoleKey(){}
public GroupRoleKey(Long userID, Long roleID, Long groupID) {
this.userID = userID;
this.roleID = roleID;
this.groupID = groupID
}
Honestly I'm not sure if this is even the best way to represent the User - Role - Group relation, any advice would be appreciated. I need to display a Users Roles within each group they belong to, for example I may want to display Bob's Roles Admin and Teacher for Group 1 and role Group Admin for group 2. I need to know which roles correspond to what group and what roles correspond to what user.
EDIT:
Group Entity:
#Table(name="FocusGroups")
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "groupID")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long groupID;
private String groupName;
#ManyToMany
#JoinTable(name = "GroupMembers",
joinColumns = #JoinColumn(
name = "groupID"),
inverseJoinColumns = #JoinColumn(
name = "userID"))
private Set<User> groupMembers = new HashSet<>();
#ManyToMany
#JoinTable(name = "GroupRoles",
joinColumns =
#JoinColumn(
name = "groupID"),
inverseJoinColumns = #JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
#ManyToOne(fetch = FetchType.EAGER, optional = true)
#JoinColumn(name="frameworkID", nullable = true)
private Framework framework;
public Group(){}
public Group(String groupName, Set<User> groupMembers, Framework framework) {
this.groupName = groupName;
this.groupMembers = groupMembers;
this.framework = framework;
}
public Long getGroupID() {
return groupID;
}
public void setGroupID(Long groupID) {
this.groupID = groupID;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Set<User> getGroupMembers() {
return groupMembers;
}
public void setGroupMembers(Set<User> groupMembers) {
this.groupMembers = groupMembers;
}
public void addMembers(Set<User> groupMembers){
this.groupMembers.addAll(groupMembers);
}
public void addMember(User groupMember){
this.groupMembers.add(groupMember);
}
public String groupMembersToString(){
String out = "";
int count = 0;
if(groupMembers.size() > 0){
for(User user: groupMembers){
if(count >= 1){
out += ", ";
}
out += user.getUsername();
count++;
}
}else{
out = "No members";
}
return out;
}
public boolean hasMember(String groupMemberName) {
for (User member : this.groupMembers) {
if (member.getUsername().equals(groupMemberName)) {
return true;
}
}
return false;
}
public User getGroupMember(String groupMemberName){
for(User member: this.groupMembers){
if(member.getUsername().equals(groupMemberName)){
return member;
}
}
return null;
}
public Framework getFramework() {
return framework;
}
public void setFramework(Framework framework) {
this.framework = framework;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
Role:
#Entity
#Table(name = "Roles")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long roleID;
private String roleName;
#ManyToMany
#JoinTable(name = "GroupRoles",
joinColumns =
#JoinColumn(
name = "roleID"),
inverseJoinColumns = #JoinColumn(
name = "groupID", nullable = true))
private Set<Group> groups = new HashSet<>();
protected Role(){}
public Role(String roleName){
this.roleName = roleName;
}
public Long getId() {
return roleID;
}
public void setId(Long id) {
this.roleID = id;
}
public String getName() {
return roleName;
}
public void setName(String roleName) {
this.roleName = roleName;
}
}
User:
#Table(name="Users")
#Entity
#NamedStoredProcedureQueries({
#NamedStoredProcedureQuery(
name = "userRating",
procedureName = "CalculateUserRating",
parameters = {
#StoredProcedureParameter(
name = "userID",
type = Long.class,
mode = ParameterMode.IN),
#StoredProcedureParameter(
name = "focusID",
type = Long.class,
mode = ParameterMode.IN),
#StoredProcedureParameter(
name = "userRating",
type = BigDecimal.class,
mode = ParameterMode.OUT)
})
})
//store a base rating?
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userID;
#Column(name = "userHashedPassword")
private String password;
#Column(name = "userName")
private String userName;
#Column(name = "userEmail")
private String email;
#ManyToMany
#JoinTable(name = "GroupMembers",
joinColumns = #JoinColumn(
name = "userID"),
inverseJoinColumns = #JoinColumn(
name = "groupID"))
private Set<Group> usersGroups = new HashSet<>();
#ManyToMany
#JoinTable(name = "UserRoles",
joinColumns = #JoinColumn(
name = "userID"),
inverseJoinColumns = #JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
#OneToMany(mappedBy = "user")
private Set<Rating> ratings;
protected User(){}
public User(String userHashedPassword, String userName, String email, Set<Role> roles){
this.password = userHashedPassword;
this.userName = userName;
this.email = email;
this.roles = roles;
}
public User(String userName, String userHashedPassword){
this.userName = userName;
this.password = userHashedPassword;
}
public Long getUserId() {
return userID;
}
public void setId(Long userID) {
this.userID = userID;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;
}
public String getUsername() {
return userName;
}
public void setUsername(String name) {
this.userName = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public Set<Rating> getRatings() {
return ratings;
}
public void setRatings(Set<Rating> ratings) {
this.ratings = ratings;
}
public String rolesToString(){
String outputRoles = "";
int count = 0;
for(Role role: roles){
if(count >= 1){
outputRoles += ", ";
}
outputRoles += role.getName();
count++;
}
return outputRoles;
}
public void removeRole(Role role){
this.roles.remove(role);
}
public Set<Group> getGroups() {
return usersGroups;
}
public void addGroup(Group group) {
this.usersGroups.add(group);
}
public void addGroups(Set<Group> groups) {
this.usersGroups.addAll(groups);
}
public Set<Group> getUsersGroups() {
return usersGroups;
}
public void setUsersGroups(Set<Group> usersGroups) {
this.usersGroups = usersGroups;
}
public String groupsToString(){
String outputGroups = "";
int count = 0;
if(usersGroups.size() > 0){
for(Group group: usersGroups){
if(count >= 1){
outputGroups += ", ";
}
outputGroups += group.getGroupName();
count++;
}
}else{
outputGroups = "None";
}
return outputGroups;
}
}
i'm new in spring.I have a project that name is SampleStore. some entities created in my projects, such as User, UserRole, Product, Orders, CartItem and .... but i have a problem. when i try add new user app does it without error and new record inserted in databse. but when i try to insert new order i'll get error.
User.java
#Entity
#Table(name = "users")
public class User implements Serializable, UserDetails {
private static final long serialVersionUID = -8245107356306518473L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "username", nullable = false, unique = true, length = 50)
private String username;
#Column(name = "password", nullable = false, length = 60)
private String password;
#Column(name = "enabled", nullable = true, columnDefinition = "tinyint(1) default 1")
private boolean enabled;
#Column(name = "expired", nullable = true, columnDefinition = "tinyint(1) default 1")
private boolean accountNonExpired;
#Column(name = "locked", nullable = true, columnDefinition = "tinyint(1) default 1")
private boolean accountNonLocked;
#Column(name = "credential", nullable = true, columnDefinition = "tinyint(1) default 1")
private boolean credentialsNonExpired;
#Column(name = "gender", nullable = true)
private char gender;
#Column(name = "address", nullable = true)
private String address;
#Column(name = "phonenumber", nullable = true)
private String phoneNumber;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private Set<UserRole> userRoles = new HashSet<UserRole>(0);
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private List<Comment> comments = new ArrayList<Comment>();
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
private List<Orders> orders = new ArrayList<Orders>();
public User() {
}
public User(String username, String password, boolean enabled) {
this.username = username;
this.password = password;
this.enabled = enabled;
}
public User(String username, String password, boolean enabled, Set<UserRole> userRoles) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.userRoles = userRoles;
}
public User(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, Set<UserRole> authorities) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.accountNonExpired = accountNonExpired;
this.credentialsNonExpired = credentialsNonExpired;
this.accountNonLocked = accountNonLocked;
this.userRoles = authorities;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public List<Orders> getOrders() {
return orders;
}
public void setOrders(List<Orders> orders) {
this.orders = orders;
}
#Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", enabled=" + enabled
+ ", gender=" + gender + ", address=" + address + ", phoneNumber=" + phoneNumber + ", userRoles="
+ userRoles + "]";
}
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority> result = new ArrayList<GrantedAuthority>(setAuths);
return result;
}
public boolean isAccountNonExpired() {
return accountNonExpired;
}
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
}
UserRole.java
#Entity
#Table(name = "user_roles", uniqueConstraints = #UniqueConstraint(columnNames = { "username", "role" }))
public class UserRole {
private Integer userRoleId;
private User user;
private String role;
public UserRole() {
}
public UserRole(User user, String role) {
this.user = user;
this.role = role;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_role_id", unique = true, nullable = false)
public Integer getUserRoleId() {
return this.userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "username", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name = "role", nullable = false, length = 45)
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
}
Orders.java
#Entity
#Table(name = "orders")
public class Orders implements Serializable {
private static final long serialVersionUID = -3672662224925418969L;
#Id
#Column(name = "ord_id", nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#DateTimeFormat(pattern = "yyyy-mm-dd")
#Column(name = "orderDate", nullable = false)
private Date orderDate;
#DateTimeFormat(pattern = "yyyy-mm-dd")
#Column(name = "delivery", nullable = false)
private Date deliveryDate;
#Column(name = "success", nullable = true, columnDefinition = "tinyint(1) default 0")
private boolean success;
#Column(name = "cancel", nullable = true, columnDefinition = "tinyint(1) default 0")
private boolean canceled;
#Column(name = "cause", nullable = true)
private String cancelCause;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "order")
private List<CartItem> items = new ArrayList<CartItem>();
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name="username",nullable=false)
private User user;
public Orders() {
}
public Orders(Date deliveryDate, List<CartItem> items, User user) {
this.orderDate = new Date();
this.deliveryDate = deliveryDate;
this.items = items;
this.user = user;
}
public Orders(List<CartItem> items, User user) {
this.orderDate = new Date();
this.items = items;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public Date getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(Date deliveryDate) {
this.deliveryDate = deliveryDate;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public boolean isCanceled() {
return canceled;
}
public void setCanceled(boolean canceled) {
this.canceled = canceled;
}
public String getCancelCause() {
return cancelCause;
}
public void setCancelCause(String cancelCause) {
this.cancelCause = cancelCause;
}
public List<CartItem> getItems() {
return items;
}
public void setItems(List<CartItem> items) {
this.items = items;
}
}
CartItem.java
#Entity
#Table(name = "saleitems", uniqueConstraints = {})
public class CartItem implements Serializable {
private static final long serialVersionUID = 7968604053015663078L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false)
private Long id;
#Column(name = "prd_id", nullable = false)
private Product product;
#Column(name = "quantity", nullable = false, columnDefinition = "int(11) default 1")
private Integer quantity;
#Column(name = "totalprice", nullable = false)
private BigDecimal totalprice;
#ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "orderid", nullable = false)
private Orders order;
public CartItem(Product product, Integer quantity) {
this.product = product;
this.quantity = quantity;
setTotalprice();
}
public CartItem() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public BigDecimal getTotalprice() {
return totalprice;
}
public void setTotalprice() {
this.totalprice = getProduct().getPrice().multiply(new BigDecimal(getQuantity()));
}
public Orders getOrder() {
return order;
}
public void setOrder(Orders order) {
this.order = order;
}
}
here one part of my controller code that user to save new user and save new order.
#RequestMapping(value = "/saveuser", method = RequestMethod.POST)
public ModelAndView saveNewUser(#ModelAttribute User user) {
ModelAndView model = new ModelAndView();
user.setEnabled(true);
user.setAccountNonExpired(true);
user.setAccountNonLocked(true);
user.setCredentialsNonExpired(true);
UserRole role = new UserRole(user, "ROLE_USER");
Set<UserRole> roles = new HashSet<UserRole>();
roles.add(role);
user.setUserRoles(roles);
String result = userService.addUser(user);
if (!result.toLowerCase().startsWith("error")) {
model.setViewName("loginForm");
} else {
model.setViewName("newuser");
model.addObject("error", result);
}
return model;
}
#SuppressWarnings("unchecked")
#RequestMapping(value = "/store/addorder", method = RequestMethod.GET)
public ModelAndView addOrder(HttpSession session) {
ModelAndView model = new ModelAndView();
// create list of products that we have to add in orders
System.err.println("item get to retrieving---------------");
List<CartItem> items = (List<CartItem>) session.getAttribute("cart");
for (CartItem cartItem : items) {
System.err.println(cartItem.getProduct());
}
// find user by username to set orders userinfo
System.err.println("user information get to retriving---------------");
String username = SecurityContextHolder.getContext().getAuthentication().getName();
User user = userService.findByUsername(username);
System.err.println(user);
// new order generated and setter methods invoke
System.err.println("new order generated-------------------");
Orders order = new Orders(items, user);
Date d = new Date();
Date delivery = StoreUtils.deliveryDate(d, 3);
order.setOrderDate(d);
order.setDeliveryDate(delivery);
order.setUser(user);
order.setItems(items);
String addOrders = orderService.addOrders(order);
System.err.println("new order add status " + addOrders + "-------------");
System.err.println(order);
// change product quantity after adding new order
for (int i = 0; i < items.size(); i++) {
Integer qSale = items.get(i).getQuantity() * (-1);
productService.rechargeProduct(items.get(i).getProduct(), qSale);
}
if (!addOrders.toLowerCase().contains("error")) {
model.setViewName("successorder");
model.addObject("order", order);
model.addObject("message", addOrders);
session.setAttribute("cart", null);
} else {
session.setAttribute("error", addOrders);
model.setViewName("redirect:/addtocartlist");
}
return model;
}
finally, here my code in dao class that save user and order.
UserDaoImpl.java
public String addUser(User user) {
String result = "";
String pass = encoder.encode(user.getPassword());
user.setPassword(pass);
try {
session().save(user);
session().flush();
result = "success";
} catch (Exception e) {
if (e.getCause().getMessage().toLowerCase().contains("duplicate"))
result = "error :user is already joined to store!";
else
result = "error :" + e.getCause().getMessage();
}
return result;
}
OrderDaoImpl.java
public String addOrders(Orders orders) {
String result = "";
try {
session().save(orders);
result = "success";
} catch (Exception e) {
if (e.getCause() != null)
if (e.getCause().getMessage().toLowerCase().contains("duplicate"))
result = "error this order already was exist";
else
result = "error " + e.getCause().getMessage();
else {
result = "error " + e.getMessage();
}
System.err.println(result);
} finally {
session().clear();
}
return result;
}
All codes are similar, but results are diffrent. when try to add new order I get this exception:
not-null property references a null or transient value:com.softup.store.entity.CartItem.order
Set both sides of relation. On every item call setOrder(). On user setOrder() also.
Above is the JPA Class
public class UsersDaoJpa extends BaseDaoJpa<Users> implements UsersDao {
public UsersDaoJpa() {
super(Users.class, "Users");
}
#Override
public List<Users> findByRegisteredUserEmail(String emailId) {
Query query = getEntityManager().createQuery("SELECT us FROM Users AS us WHERE us.emailId =:emailId");
query.setParameter("emailId", emailId);
return query.getResultList();
}
#Override
public List<Users> findByRegisteredUserPhone(String mobileNo) {
Query query = getEntityManager().createQuery("SELECT us FROM Users AS us WHERE us.mobileNo =:mobileNo");
query.setParameter("mobileNo", mobileNo);
return query.getResultList();
}
#Override
public List<Users> FindUsersByEmailPhoneRole(String emailId, String mobileNo, String userRole) {
Query query = getEntityManager().createQuery("SELECT us FROM Users AS us WHERE us.mobileNo =:mobileNo AND us.emailId =:emailId AND us.userRole =:userRole");
query.setParameter("mobileNo", mobileNo);
query.setParameter("emailId", emailId);
query.setParameter("userRole", userRole);
return query.getResultList();
}
#Override
public List<Users> checkUserNameAvailability(String userName) {
System.out.println("the username is " + userName);
Query query = getEntityManager().createQuery("SELECT us FROM Users AS us WHERE us.userName =:userName");
System.out.println("the username2 is " + userName);
query.setParameter("userName", userName);
System.out.println("the username3 is " + userName);
return query.getResultList();
}
#Override
public List<Users> checkEmailNMobileVerificationByUname(String userName, Boolean bolVal) {
Query query = getEntityManager().createQuery("SELECT us FROM Users AS us WHERE us.userName =:userName AND us.mobileVerifyStatus =:bolVal AND us.emailVerifyStatus =:bolVal");
query.setParameter("userName", userName);
query.setParameter("bolVal", bolVal);
return query.getResultList();
}
}
Above is the Domain Class or entity class against my db table
#Entity
#Table(name = "users")
public class Users extends BaseDomain {
private static final long serialVersionUID = 1L;
#Basic(optional = false)
#Column(name = "full_name")
private String fullName;
#Basic(optional = false)
#Column(name = "email_id")
private String emailId;
#Basic(optional = false)
#Column(name = "mobile_no")
private String mobileNo;
#Basic(optional = false)
#Column(name = "dob")
#Temporal(TemporalType.DATE)
private Date dob;
#Basic(optional = false)
#Column(name = "user_name")
private String userName;
#Basic(optional = false)
#Column(name = "password")
private String password;
#Basic(optional = false)
#Column(name = "email_verify_code")
private String emailVerifyCode;
#Basic(optional = false)
#Column(name = "mobile_verify_code")
private String mobileVerifyCode;
#Basic(optional = false)
#Column(name = "email_verify_status")
private boolean emailVerifyStatus;
#Basic(optional = false)
#Column(name = "mobile_verify_status")
private boolean mobileVerifyStatus;
#Basic(optional = false)
#Column(name = "user_role")
private String userRole;
#Basic(optional = false)
#Column(name = "login _utc")
#Temporal(TemporalType.TIMESTAMP)
private Date loginUtc;
#Basic(optional = false)
#Column(name = "registration_utc")
#Temporal(TemporalType.TIMESTAMP)
private Date registrationUtc;
#Basic(optional = false)
#Column(name = "is_approved")
private boolean isApproved;
#Basic(optional = false)
#Column(name = "is_blocked")
private boolean isBlocked;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private Collection<AdvisorDocument> advisorDocumentCollection;
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getMobileNo() {
return mobileNo;
}
public void setMobileNo(String mobileNo) {
this.mobileNo = mobileNo;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmailVerifyCode() {
return emailVerifyCode;
}
public void setEmailVerifyCode(String emailVerifyCode) {
this.emailVerifyCode = emailVerifyCode;
}
public String getMobileVerifyCode() {
return mobileVerifyCode;
}
public void setMobileVerifyCode(String mobileVerifyCode) {
this.mobileVerifyCode = mobileVerifyCode;
}
public boolean getEmailVerifyStatus() {
return emailVerifyStatus;
}
public void setEmailVerifyStatus(boolean emailVerifyStatus) {
this.emailVerifyStatus = emailVerifyStatus;
}
public boolean getMobileVerifyStatus() {
return mobileVerifyStatus;
}
public void setMobileVerifyStatus(boolean mobileVerifyStatus) {
this.mobileVerifyStatus = mobileVerifyStatus;
}
public String getUserRole() {
return userRole;
}
public void setUserRole(String userRole) {
this.userRole = userRole;
}
public Date getLoginUtc() {
return loginUtc;
}
public void setLoginUtc(Date loginUtc) {
this.loginUtc = loginUtc;
}
public Date getRegistrationUtc() {
return registrationUtc;
}
public void setRegistrationUtc(Date registrationUtc) {
this.registrationUtc = registrationUtc;
}
public boolean getIsApproved() {
return isApproved;
}
public void setIsApproved(boolean isApproved) {
this.isApproved = isApproved;
}
public boolean getIsBlocked() {
return isBlocked;
}
public void setIsBlocked(boolean isBlocked) {
this.isBlocked = isBlocked;
}
public Collection<AdvisorDocument> getAdvisorDocumentCollection() {
return advisorDocumentCollection;
}
public void setAdvisorDocumentCollection(Collection<AdvisorDocument> advisorDocumentCollection) {
this.advisorDocumentCollection = advisorDocumentCollection;
}
}
And the error its throwing that its a mysql sysntax error exception. But according to me the code should work properly but dont know why isn't it not working .
the error that its throwing is as follows
I have this part of database schema:
and this User entity:
#Entity
#Table(name = "user", catalog = "ats")
public class User implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private String username;
private boolean enabled;
private Role role;
private ClientVersion clientVersion;
private ClientLicense clientLicense;
#JsonIgnore
private Set<NotificationHasUser> notificationHasUsers = new HashSet<NotificationHasUser>(0);
public User() {
}
public User(String username, boolean enabled) {
this.username = username;
this.enabled = enabled;
}
public User(String username, boolean enabled, Role role, Set<NotificationHasUser> notificationHasUsers) {
this.username = username;
this.enabled = enabled;
this.role = role;
this.notificationHasUsers = notificationHasUsers;
}
#Id
#Column(name = "username", unique = true, nullable = false, length = 45)
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "enabled", nullable = false)
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_role", nullable = false)
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_clientVersion", nullable = false)
public ClientVersion getClientVersion() {
return this.clientVersion;
}
public void setClientVersion(ClientVersion clientVersion) {
this.clientVersion = clientVersion;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user")
public Set<NotificationHasUser> getNotificationHasUser() {
return this.notificationHasUsers;
}
public void setNotificationHasUser(Set<NotificationHasUser> notificationHasUsers) {
this.notificationHasUsers = notificationHasUsers;
}
#OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
public ClientLicense getClientLicense(){
return this.clientLicense;
}
public void setClientLicense(ClientLicense clientLicense){
this.clientLicense = clientLicense;
}
}
All works fine until I add a new clientlicense. If I add this I receive an infinite loop:
Could not write content: Infinite recursion (StackOverflowError) (through reference chain: com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]->com.domain.ClientLicense["user"]->com.domain.User["clientLicense"]-....
This is my ClientLicense entity
#Entity
#Table(name = "clientlicense", catalog = "ats")
public class ClientLicense implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idClientLicense;
private Date startDate;
private Date endDate;
private int counter;
private String macAddress;
private String cpuId;
private User user;
public ClientLicense() {
}
/**
* #param startDate
* #param endDate
* #param counter
* #param macAddress
* #param cpuId
* #param users
*/
public ClientLicense(Date startDate, Date endDate, int counter, String macAddress, String cpuId, User user) {
super();
this.startDate = startDate;
this.endDate = endDate;
this.counter = counter;
this.setMacAddress(macAddress);
this.setCpuId(cpuId);
this.user = user;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_clientLicense", unique = true, nullable = false)
public Integer getIdClientLicense() {
return this.idClientLicense;
}
public void setIdClientLicense(Integer idClientLicense) {
this.idClientLicense = idClientLicense;
}
#Column(name = "startDate", nullable = false)
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
#Column(name = "endDate", nullable = false)
public Date getEndDate() {
return this.endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
#Column(name = "counter", nullable = false)
public int getCounter() {
return this.counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
/**
* #return the macAddress
*/
#Column(name = "macAddress", nullable = false)
public String getMacAddress() {
return macAddress;
}
/**
* #param macAddress the macAddress to set
*/
public void setMacAddress(String macAddress) {
this.macAddress = macAddress;
}
/**
* #return the cpuId
*/
#Column(name = "cpuId", nullable = false)
public String getCpuId() {
return cpuId;
}
/**
* #param cpuId the cpuId to set
*/
public void setCpuId(String cpuId) {
this.cpuId = cpuId;
}
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "id_username")
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
}
This is my first OneToOne relationship, what is the correct annotation that I have to use? I read some example but I don't understand fine, they are different each other.
try something like this.
public class User {
private ClientLicense clientLicense;
#OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
public ClientLicense getClientLicense() {
return this.clientLicense;
}
}
public class ClientLicense {
private User user;
#OneToOne
#JoinColumn(name = "id_username")
public User getUser() {
return this.user;
}
}
The problem is that the two entities have no way of finding out that the two fields are actually specifying a single relationship. So hibernate assumes that they are not the same relationship and therefore tries to fetch them (because one-to-one relationships are fetched eagerly by default).
Add #OneToOne(mappedBy = "user") before the clientLicense field in the User class to tell hibernate that this field is "mapped by" the same column as the user field in the ClientLicense class
I have a problem. Here my entities user and userRole
User
package com.springapp.model;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "users", catalog = "users")
public class User {
private String username;
private String password;
private boolean enabled;
private String email;
private String token;
private Set<UserRole> userRole = new HashSet<UserRole>(0);
public User() {
this.enabled=false;
}
#Column(name = "token",
nullable = false, length = 80)
public String getToken() {
return this.token;
}
public void setToken(String token) {
this.token = token;
}
public String getEmail() {
return this.email;
}
#Column(name = "email",
nullable = false, length = 80)
public void setEmail(String email) {
this.email = email;
}
#Id
#Column(name = "username", unique = true,
nullable = false, length = 45)
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password",
nullable = false, length = 60)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "enabled", nullable = false)
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
public Set<UserRole> getUserRole() {
return this.userRole;
}
public void setUserRole(Set<UserRole> userRole) {
this.userRole = userRole;
}
}
UserRole
package com.springapp.model;
import javax.persistence.*;
import static javax.persistence.GenerationType.IDENTITY;
#Entity
#Table(name = "user_roles", uniqueConstraints = #UniqueConstraint(
columnNames = { "role", "username" }))
public class UserRole{
private Integer userRoleId;
private User user;
private String role;
public UserRole() {
}
public UserRole(User user, String role) {
this.user = user;
this.role = role;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_role_id",
unique = true, nullable = false)
public Integer getUserRoleId() {
return this.userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "username", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
#Column(name = "role", nullable = false, length = 45)
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
}
Now I want to get list of users with lists of their roles to json using gson lib
List<User> users = userService.showAllUsers();
Gson gson = new Gson();
return gson.toJson(users);
But it fails with stackoverflow error. I think it's because every user refers to roles and roles refers to users (because we have User user in Userroles and Set of roles in users). And it turns "recursion". How can I avoid this error?
That happens when you bidirectional associations and JSon doesn't ignore one side.
You need to mark the many-to-one side with #JsonIgnore:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "username", nullable = false)
#JsonIgnore
public User getUser() {
return this.user;
}