I'm using hibernate-core in a maven project and I want to create the entities for the following database: db_schema
I'm just starting to learn hibernate, so please bear with me on this one. I know that it might be a stupid mistake but I just can't figure it out.
I'm getting the following exception when I try to test the code:
org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: entity.User.groups[entity.IsIn]
I will list the code for my entities below
User
package entity;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "userId")
private int userId;
#OneToMany(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<IsIn> groups = new ArrayList<>();
#Column(name = "customerName", nullable = false)
private String customerName;
#Column(name = "password", nullable = false)
private String password;
#Column(name = "email", nullable = false)
private String email;
#Column(name = "is_active", nullable = false)
private boolean is_active;
#Column(name = "notificationType", nullable = false)
private String notificationType;
#Column(name = "create_date", nullable = false)
private String create_date;
public User() { }
public User(String customerName, String password, String email, boolean is_active, String notificationType, String create_date) {
this.customerName = customerName;
this.password = password;
this.email = email;
this.is_active = is_active;
this.notificationType = notificationType;
this.create_date = create_date;
}
public void addGroup(Group group) {
IsIn isIn = new IsIn(this, group);
groups.add(isIn);
}
public void removeGroup(Group group) {
for (Iterator<IsIn> iterator = groups.iterator();
iterator.hasNext(); ) {
IsIn isIn = iterator.next();
if (isIn.getUser().equals(this) &&
isIn.getGroup().equals(group)) {
iterator.remove();
isIn.setUser(null);
isIn.setGroup(null);
}
}
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isIs_active() {
return is_active;
}
public void setIs_active(boolean is_active) {
this.is_active = is_active;
}
public String getNotificationType() {
return notificationType;
}
public void setNotificationType(String notificationType) {
this.notificationType = notificationType;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
}
Group
package entity;
import org.hibernate.annotations.NaturalIdCache;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "group")
#NaturalIdCache
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "groupId")
private int groupId;
#Column(name = "groupName")
private String groupName;
#Column(name = "notificationMessage", nullable = false)
private String notificationMessage;
#Column(name = "create_date", nullable = false)
private String create_date;
#OneToOne
#JoinColumn(name = "created_by")
private User created_by;
#Column(name = "isPrivate")
private boolean isPrivate;
public Group() { }
public Group(String groupName, String notificationMessage, String create_date, boolean isPrivate) {
this.groupName = groupName;
this.notificationMessage = notificationMessage;
this.create_date = create_date;
this.isPrivate = isPrivate;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
Group group = (Group) o;
return Objects.equals(groupId, group.getGroupId());
}
#Override
public int hashCode() { return Objects.hash(groupId); }
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getNotificationMessage() { return notificationMessage; }
public void setNotificationMessage(String notificationMessage) {
this.notificationMessage = notificationMessage;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
public boolean isPrivate() {
return isPrivate;
}
public void setPrivate(boolean aPrivate) {
isPrivate = aPrivate;
}
public User getCreated_by() {
return created_by;
}
public void setCreated_by(User created_by) {
this.created_by = created_by;
}
}
UserGroupId (Embeddable)
package Embedded;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;
#Embeddable
public class UserGroupId implements Serializable {
#Column(name = "userId")
private int userId;
#Column(name = "groupId")
private int groupId;
private UserGroupId() {}
public UserGroupId(int userId, int groupId) {
this.userId = userId;
this.groupId = groupId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
UserGroupId that = (UserGroupId) o;
return Objects.equals(userId, that.userId) &&
Objects.equals(groupId, that.groupId);
}
#Override
public int hashCode() {
return Objects.hash(userId, groupId);
}
}
IsIn
package entity;
import Embedded.UserGroupId;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "isin")
public class IsIn {
#EmbeddedId
private UserGroupId id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("userId")
private User user;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("groupId")
private Group group;
#OneToOne
#JoinColumn(name = "typeId")
private UserType typeId;
#Column(name = "isBlocked", nullable = false)
private boolean isBlocked;
private IsIn() {}
public IsIn(User user, Group group) {
this.user = user;
this.group = group;
this.id = new UserGroupId(user.getUserId(), group.getGroupId());
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
IsIn that = (IsIn) o;
return Objects.equals(user, that.user) &&
Objects.equals(group, that.group);
}
#Override
public int hashCode() {
return Objects.hash(user, group);
}
public User getUser() {
return user;
}
public Group getGroup() {
return group;
}
public void setUser(User user) {
this.user = user;
}
public void setGroup(Group group) {
this.group = group;
}
public UserType getTypeId() {
return typeId;
}
public void setTypeId(UserType typeId) {
this.typeId = typeId;
}
public boolean isBlocked() {
return isBlocked;
}
public void setBlocked(boolean blocked) {
isBlocked = blocked;
}
}
Privilege
package entity;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "privilege")
public class Privilege {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "privilegeId")
private int privilegeId;
#Column(name = "privilegeName", nullable = false)
private String privilegeName;
#ManyToMany(mappedBy = "privilege")
private Set<UserType> usertypes = new HashSet<>();
public Privilege() {}
public Privilege(String privilegeName) {
this.privilegeName = privilegeName;
}
public int getPrivilegeId() {
return privilegeId;
}
public void setPrivilegeId(int privilegeId) {
this.privilegeId = privilegeId;
}
public String getPrivilegeName() {
return privilegeName;
}
public void setPrivilegeName(String privilegeName) { this.privilegeName = privilegeName; }
public Set<UserType> getUsertypes() { return usertypes; }
}
UserType
package entity;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "usertype")
public class UserType {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "typeId")
private int typeId;
#Column(name = "typeName", nullable = false)
private String typeName;
#ManyToMany(cascade = { CascadeType.ALL })
#JoinTable(
name = "hasprivilege",
joinColumns = { #JoinColumn(name = "typeId") },
inverseJoinColumns = { #JoinColumn(name = "privilegeId") }
)
Set<Privilege> privileges = new HashSet<>();
public UserType() { }
public UserType(String typeName) {
this.typeName = typeName;
}
public int getTypeId() {
return typeId;
}
public void setTypeId(int typeId) {
this.typeId = typeId;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
Notification
package entity;
import javax.persistence.*;
#Entity
#Table(name = "notification")
public class Notification {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "notificationId")
private int notificationId;
#Column(name = "notificationMessage", nullable = false)
private String notificationMessage;
#Column(name = "frequency", nullable = false)
private String frequency;
#Column(name = "create_date", nullable = false)
private String create_date;
#Column(name = "update_date", nullable = false)
private String update_date;
public Notification() {}
public Notification(String notificationMessage, String frequency, String create_date, String update_date) {
this.notificationMessage = notificationMessage;
this.frequency = frequency;
this.create_date = create_date;
this.update_date = update_date;
}
public int getNotificationId() {
return notificationId;
}
public void setNotificationId(int notificationId) {
this.notificationId = notificationId;
}
public String getNotificationMessage() {
return notificationMessage;
}
public void setNotificationMessage(String notificationMessage) {
this.notificationMessage = notificationMessage;
}
public String getFrequency() {
return frequency;
}
public void setFrequency(String frequency) {
this.frequency = frequency;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
public String getUpdate_date() {
return update_date;
}
public void setUpdate_date(String update_date) {
this.update_date = update_date;
}
}
Message
package entity;
import javax.persistence.*;
#Entity
#Table(name = "message")
public class Message {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "messageId")
private String messageId;
#ManyToOne
#JoinColumn(name = "userId")
private User userId;
#ManyToOne
#JoinColumn(name = "groupId")
private Group groupId;
#Column(name = "message")
private String message;
#Column(name = "create_date")
private String create_date;
#ManyToOne
#JoinColumn(name = "notificationId")
private Notification notificationId;
public Message() { }
public Message(User userId, Group groupId, String message, String create_date, Notification notificationId) {
this.userId = userId;
this.groupId = groupId;
this.message = message;
this.create_date = create_date;
this.notificationId = notificationId;
}
public String getMessageId() {
return messageId;
}
public User getUserId() {
return userId;
}
public Group getGroupId() {
return groupId;
}
public String getMessage() {
return message;
}
public String getCreate_date() {
return create_date;
}
public Notification getNotificationId() {
return notificationId;
}
}
I've been looking on Stack for a solution on similar issues but the suggestions did not help in my case. I'm kinda stuck right now.
Any help will be highly appreciated. Thank your for your time.
Related
return null using FindById
Lead.java
import java.io.Serializable;
import java.time.LocalDate;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.lang.Nullable;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "leads")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdAt", "updatedAt"},allowGetters = true)
public class Lead implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank(message = "Name is mandatory")
private String name;
#Nullable
private String phone;
#Nullable
private String standard;
#Nullable
private String stream;
#Column(columnDefinition = "boolean default true")
private Boolean active = true;
#Nullable
private String remark;
#Column(columnDefinition = "VARCHAR(30) NOT NULL default 'lead'")
private String type="lead";
#ManyToOne(fetch = FetchType.LAZY, optional = false )//, cascade = CascadeType.REMOVE)
#JoinColumn(name = "school_id", nullable = false )
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
private School school;
#Nullable
#Column(name = "school_id", insertable = false, updatable = false)
private Long schoolId;
#ManyToOne
#JoinColumn(name = "lead_status_id", nullable = false)
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
private LeadStatus leadStatus;
#Nullable
#Column(name = "lead_status_id", insertable = false, updatable = false)
private Long leadStatusId;
#ManyToOne
#JoinColumn(name = "user_id", nullable = false)
#JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
private User user;
#Nullable
#Column(name = "user_id", insertable = false, updatable = false)
private Long userId;
#CreationTimestamp
private LocalDate createdAt;
#UpdateTimestamp
private LocalDate updatedAt;
public Lead() {
// TODO Auto-generated constructor stub
}
public Lead(#NotBlank(message = "Name is mandatory") String name, String phone, String standard, String stream, String remark, String type, School school) {
this.name = name;
this.phone = phone;
this.standard = standard;
this.stream = stream;
this.remark = remark;
this.school = school;
}
public LeadStatus getLeadStatus() {
return leadStatus;
}
public void setLeadStatus(LeadStatus leadStatus) {
this.leadStatus = leadStatus;
}
public Long getLeadStatusId() {
return leadStatusId;
}
public void setLeadStatusId(Long leadStatusId) {
this.leadStatusId = leadStatusId;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getStandard() {
return standard;
}
public void setStandard(String standard) {
this.standard = standard;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public Long getSchoolId() {
return schoolId;
}
public void setSchoolId(Long schoolId) {
this.schoolId = schoolId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public LocalDate getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDate createdAt) {
this.createdAt = createdAt;
}
public LocalDate getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDate updatedAt) {
this.updatedAt = updatedAt;
}
}
Controller method
#GetMapping("/{id}")
public HashMap<String, Object> getLeadById(#PathVariable(value = "id") Long leadId) {
System.out.println(leadId);
Lead lead = leadRepository.findById(leadId).orElseThrow(() -> new ItemNotFoundException("Lead", "id", leadId));
return ResponseFormat.createFormat(lead, "Listed Successfully");
}
LeadRepository.java
package com.lakshya.lakshya.repository;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.lakshya.lakshya.model.Lead;
public interface LeadRepository extends PagingAndSortingRepository<Lead, Long> {
}
did you try to extends JpaRepository< , > ? maybe it will be the solution
public interface LeadRepository extends JpaRepository<Lead, Long> {
}
JpaRepository provides JPA related methods such as flushing the persistence context and delete records in a batch
because of this inheritance relationship, the JpaRepository contains the full API of CrudRepository and PagingAndSortingRepository.
Notify me if it works
I have 2 entities (User and Group) in a many-to-many relantionship. Therefore, I created the table IsIn, which is composed by userId, groupId (composed primary key) and 2 extra fields (typeId and isBlocked). I followed Vlad Mihalcea's tutorial on how to map the entities in such a situation -> see here
However, when I try to delete a user or a group, it doesn't work. I get the following error:
ERROR: Unknown column 'groups0_.user_userId' in 'field list'
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
I will post below my classes.
UserGroupId (Embedded)
package Embedded;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;
#Embeddable
public class UserGroupId implements Serializable {
#Column(name = "userId")
private int userId;
#Column(name = "groupId")
private int groupId;
public UserGroupId() {}
public UserGroupId(int userId, int groupId) {
this.userId = userId;
this.groupId = groupId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
UserGroupId that = (UserGroupId) o;
return Objects.equals(userId, that.userId) &&
Objects.equals(groupId, that.groupId);
}
#Override
public int hashCode() {
return Objects.hash(userId, groupId);
}
}
IsIn
package entity;
import Embedded.UserGroupId;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "isin")
public class IsIn {
#EmbeddedId
private UserGroupId id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("userId")
private User user;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("groupId")
private Group group;
#OneToOne
#JoinColumn(name = "typeId")
private UserType typeId;
#Column(name = "isBlocked", nullable = false)
private boolean isBlocked;
public IsIn() {}
public IsIn(User user, Group group) {
this.user = user;
this.group = group;
this.id = new UserGroupId(user.getUserId(), group.getGroupId());
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
IsIn that = (IsIn) o;
return Objects.equals(user, that.user) &&
Objects.equals(group, that.group);
}
#Override
public int hashCode() {
return Objects.hash(user, group);
}
public User getUser() {
return user;
}
public Group getGroup() {
return group;
}
public void setUser(User user) {
this.user = user;
}
public void setGroup(Group group) {
this.group = group;
}
public UserType getTypeId() {
return typeId;
}
public void setTypeId(UserType typeId) {
this.typeId = typeId;
}
public boolean isBlocked() {
return isBlocked;
}
public void setBlocked(boolean blocked) {
isBlocked = blocked;
}
}
User
package entity;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
#Entity
#Table(name = "`user`")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "userId" ,unique = true, nullable = false)
private int userId;
#OneToMany(
mappedBy = "user",
cascade={CascadeType.ALL},
orphanRemoval = true
)
private List<IsIn> groups = new ArrayList<>();
#Column(name = "customerName", nullable = false)
private String customerName;
#Column(name = "password", nullable = false)
private String password;
#Column(name = "email", nullable = false, unique = true)
private String email;
#Column(name = "is_active", nullable = false)
private boolean is_active;
#Column(name = "notificationType", nullable = false)
private String notificationType;
#Column(name = "create_date", nullable = false)
private String create_date;
public User() { }
public User(String customerName, String password, String email, boolean is_active, String notificationType, String create_date) {
this.customerName = customerName;
this.password = password;
this.email = email;
this.is_active = is_active;
this.notificationType = notificationType;
this.create_date = create_date;
}
public void addGroup(Group group) {
IsIn isIn = new IsIn(this, group);
groups.add(isIn);
}
public void removeGroup(Group group) {
for (Iterator<IsIn> iterator = groups.iterator();
iterator.hasNext(); ) {
IsIn isIn = iterator.next();
if (isIn.getUser().equals(this) &&
isIn.getGroup().equals(group)) {
iterator.remove();
isIn.setUser(null);
isIn.setGroup(null);
}
}
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isIs_active() {
return is_active;
}
public void setIs_active(boolean is_active) {
this.is_active = is_active;
}
public String getNotificationType() {
return notificationType;
}
public void setNotificationType(String notificationType) {
this.notificationType = notificationType;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
}
Group
package entity;
import org.hibernate.annotations.NaturalIdCache;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "`group`")
#NaturalIdCache
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "groupId")
private int groupId;
#Column(name = "groupName")
private String groupName;
#Column(name = "create_date", nullable = false)
private String create_date;
#OneToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval=true)
#JoinColumn(name = "created_by", nullable = false)
private User user;
#Column(name = "isPrivate")
private boolean isPrivate;
public Group() { }
public Group(String groupName, String create_date, User user, boolean isPrivate) {
this.groupName = groupName;
this.create_date = create_date;
this.user = user;
this.isPrivate = isPrivate;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
Group group = (Group) o;
return Objects.equals(groupId, group.getGroupId());
}
#Override
public int hashCode() { return Objects.hash(groupId); }
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public String getCreate_date() {
return create_date;
}
public void setCreate_date(String create_date) {
this.create_date = create_date;
}
public boolean isPrivate() {
return isPrivate;
}
public void setPrivate(boolean aPrivate) {
isPrivate = aPrivate;
}
public User getCreated_by() {
return user;
}
public void setCreated_by(User user) {
this.user = user;
}
}
And here is my delete method (which works for other entities, except for User and Group).
public static void deleteUserById(int userId) {
Session session = sessionFactory.openSession();
try{
session.beginTransaction();
User u = UserDAO.getUserById(userId);
session.delete(u);
session.flush();
session.getTransaction().commit();
} catch (HibernateException he) {
he.printStackTrace();
}
finally {
session.close();
}
}
Any kind of help is highly appreciated, thank you for your time.
Table DDLs
CREATE TABLE IF NOT EXISTS `chatapp`.`user` (
`userId` INT NOT NULL UNIQUE AUTO_INCREMENT,
`customerName` VARCHAR(50) NOT NULL,
`password` VARCHAR(50) NOT NULL,
`email` VARCHAR(255) NOT NULL unique,
`is_active` boolean NOT NULL,
`notificationType` VARCHAR(50) NOT NULL,
`create_date` VARCHAR(50) NOT NULL,
PRIMARY KEY (`userId`),
INDEX `userId_idx` (`userId` ASC)
);
CREATE TABLE IF NOT EXISTS `chatapp`.`group` (
`groupId` INT NOT NULL UNIQUE AUTO_INCREMENT,
`groupName` VARCHAR(255) NULL,
`create_date` VARCHAR(50) NOT NULL,
`created_by` INT NOT NULL,
`isPrivate` boolean NOT NULL,
PRIMARY KEY (`groupId`),
INDEX `groupId_idx` (`groupId` ASC),
FOREIGN KEY (`created_by`) REFERENCES `user` (`userId`)
);
CREATE TABLE IF NOT EXISTS `chatapp`.`isin` (
`userId` INT NOT NULL,
`groupId` INT NOT NULL,
`typeId` INT NOT NULL,
`isBlocked` boolean NOT NULL,
PRIMARY KEY (`userId`,`groupId`),
FOREIGN KEY (`userId`) REFERENCES `user` (`userId`),
FOREIGN KEY (`groupId`) REFERENCES `group` (`groupId`),
FOREIGN KEY (`typeId`) REFERENCES `usertype` (`typeId`)
);
Full StackTrace
here
Complete Database design
here
The #JoinColumn annotations are missing in the IsIn class.
It should look like
#Entity
#Table(name = "isin")
public class IsIn {
#EmbeddedId
private UserGroupId id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn("userId")
private User user;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn("groupId")
private Group group;
I connected my MySql database to my Java project (using Spring-MVC) with Entities.
When I try to run the application, I get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.example.WebAppProcess20.Entities.OrdersitemsEntity column: order_id (should be mapped with insert="false" update="false")
OrdersItems Entity:
package com.example.WebAppProcess20.Entities;
import javax.persistence.*;
import java.util.Objects;
#Entity
#Table(name = "ordersitems", schema = "theprocess", catalog = "")
#IdClass(OrdersitemsEntityPK.class)
public class OrdersitemsEntity {
private String productId;
private String orderId;
private Integer qunatity;
private ProductsEntity productsByProductId;
private OrdersEntity ordersByOrderId;
#Id
#Column(name = "product_id")
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
#Id
#Column(name = "orderId", nullable = false, insertable = false, updatable = false)
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#Basic
#Column(name = "qunatity")
public Integer getQunatity() {
return qunatity;
}
public void setQunatity(Integer qunatity) {
this.qunatity = qunatity;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrdersitemsEntity that = (OrdersitemsEntity) o;
return Objects.equals(productId, that.productId) &&
Objects.equals(orderId, that.orderId) &&
Objects.equals(qunatity, that.qunatity);
}
#Override
public int hashCode() {
return Objects.hash(productId, orderId, qunatity);
}
#ManyToOne
#JoinColumn(name = "product_id", referencedColumnName = "product_id", nullable = false)
public ProductsEntity getProductsByProductId() {
return productsByProductId;
}
public void setProductsByProductId(ProductsEntity productsByProductId) {
this.productsByProductId = productsByProductId;
}
#ManyToOne
#JoinColumn(name = "orderId", referencedColumnName = "orderId", nullable = false)
public OrdersEntity getOrdersByOrderId() {
return ordersByOrderId;
}
public void setOrdersByOrderId(OrdersEntity ordersByOrderId) {
this.ordersByOrderId = ordersByOrderId;
}
}
Orders Entity:
package com.example.WebAppProcess20.Entities;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Objects;
#Entity
#Table(name = "orders", schema = "theprocess", catalog = "")
public class OrdersEntity {
private String orderId;
private String notesFromClient;
private Timestamp orderDate;
private String orderStatus;
private String totalSum;
private ClientsEntity clientsByClientId;
private Collection<OrdersitemsEntity> ordersitemsByOrderId;
#Id
#Column(name = "orderId")
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#Basic
#Column(name = "notes_from_client")
public String getNotesFromClient() {
return notesFromClient;
}
public void setNotesFromClient(String notesFromClient) {
this.notesFromClient = notesFromClient;
}
#Basic
#Column(name = "order_date")
public Timestamp getOrderDate() {
return orderDate;
}
public void setOrderDate(Timestamp orderDate) {
this.orderDate = orderDate;
}
#Basic
#Column(name = "order_status")
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
#Basic
#Column(name = "totalSum")
public String getTotalSum() {
return totalSum;
}
public void setTotalSum(String totalSum) {
this.totalSum = totalSum;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrdersEntity that = (OrdersEntity) o;
return Objects.equals(orderId, that.orderId) &&
Objects.equals(notesFromClient, that.notesFromClient) &&
Objects.equals(orderDate, that.orderDate) &&
Objects.equals(orderStatus, that.orderStatus) &&
Objects.equals(totalSum, that.totalSum);
}
#Override
public int hashCode() {
return Objects.hash(orderId, notesFromClient, orderDate, orderStatus, totalSum);
}
#ManyToOne
#JoinColumn(name = "client_id", referencedColumnName = "client_id", nullable = false)
public ClientsEntity getClientsByClientId() {
return clientsByClientId;
}
public void setClientsByClientId(ClientsEntity clientsByClientId) {
this.clientsByClientId = clientsByClientId;
}
#OneToMany(mappedBy = "ordersByOrderId")
public Collection<OrdersitemsEntity> getOrdersitemsByOrderId() {
return ordersitemsByOrderId;
}
public void setOrdersitemsByOrderId(Collection<OrdersitemsEntity> ordersitemsByOrderId) {
this.ordersitemsByOrderId = ordersitemsByOrderId;
}
}
OrdersItemsPK class:
package com.example.WebAppProcess20.Entities;
import javax.persistence.Column;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Objects;
public class OrdersitemsEntityPK implements Serializable {
private String productId;
private String orderId;
#Column(name = "product_id")
#Id
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
#Column(name = "orderId")
#Id
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrdersitemsEntityPK that = (OrdersitemsEntityPK) o;
return Objects.equals(productId, that.productId) &&
Objects.equals(orderId, that.orderId);
}
#Override
public int hashCode() {
return Objects.hash(productId, orderId);
}
}
Products Entity:
package com.example.WebAppProcess20.Entities;
import javax.persistence.*;
import java.util.Collection;
import java.util.Objects;
#Entity
#Table(name = "products", schema = "theprocess", catalog = "")
public class ProductsEntity {
private String productId;
private Integer availableInStock;
private String brand;
private String image;
private Integer price;
private String productCategoryTree;
private String productName;
private Integer rating;
private Collection<OrdersitemsEntity> ordersitemsByProductId;
#Id
#Column(name = "product_id")
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
#Basic
#Column(name = "available_in_stock")
public Integer getAvailableInStock() {
return availableInStock;
}
public void setAvailableInStock(Integer availableInStock) {
this.availableInStock = availableInStock;
}
#Basic
#Column(name = "brand")
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
#Basic
#Column(name = "image")
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
#Basic
#Column(name = "price")
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
#Basic
#Column(name = "product_category_tree")
public String getProductCategoryTree() {
return productCategoryTree;
}
public void setProductCategoryTree(String productCategoryTree) {
this.productCategoryTree = productCategoryTree;
}
#Basic
#Column(name = "product_name")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#Basic
#Column(name = "rating")
public Integer getRating() {
return rating;
}
public void setRating(Integer rating) {
this.rating = rating;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProductsEntity that = (ProductsEntity) o;
return Objects.equals(productId, that.productId) &&
Objects.equals(availableInStock, that.availableInStock) &&
Objects.equals(brand, that.brand) &&
Objects.equals(image, that.image) &&
Objects.equals(price, that.price) &&
Objects.equals(productCategoryTree, that.productCategoryTree) &&
Objects.equals(productName, that.productName) &&
Objects.equals(rating, that.rating);
}
#Override
public int hashCode() {
return Objects.hash(productId, availableInStock, brand, image, price, productCategoryTree, productName, rating);
}
#OneToMany(mappedBy = "productsByProductId")
public Collection<OrdersitemsEntity> getOrdersitemsByProductId() {
return ordersitemsByProductId;
}
public void setOrdersitemsByProductId(Collection<OrdersitemsEntity> ordersitemsByProductId) {
this.ordersitemsByProductId = ordersitemsByProductId;
}
}
Ordersitems connects between Orders and Products - it contains the products of each order, so productId and orderId both foreign keys in Orderitems.
I think I understand the error, if I'm not wrong, the reapeted column error refers to:
#Id
#Column(name = "orderId", nullable = false, insertable = false, updatable = false)
public String getOrderId() {
return orderId;
}
and:
#ManyToOne
#JoinColumn(name = "orderId", referencedColumnName = "orderId", nullable = false)
public OrdersEntity getOrdersByOrderId() {
return ordersByOrderId;
}
public void setOrdersByOrderId(OrdersEntity ordersByOrderId) {
this.ordersByOrderId = ordersByOrderId;
}
But whatever I tried to do didn't solve the problem or even added other errors.
Can you please help me to solve this problem?
Thanks!
I am building an order tracking system in Spring Boot, using Hibernate annotations and Repositories. I have an Order class, which can have a list of OrderItems. These map to a ORDER and ORDER_ITEMS table respectively. The code I have representing the two is below.
Order.java
package net.township.order;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
#Entity
#Table(name = "orders")
public class Order {
public Order() {
}
public Order(long merchantId, String firstDeliveryName, String
lastDeliveryName, String deliveryAddress, String status, Date createDate,
Date updateDate) {
this.merchantId = merchantId;
this.lastDeliveryName = lastDeliveryName;
this.firstDeliveryName = firstDeliveryName;
this.deliveryAddress = deliveryAddress;
this.status = status;
this.createDate = createDate;
this.updateDate = updateDate;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "order_id", unique = true)
private long orderId;
#Column(name = "merchant_id")
private long merchantId;
#Column(name = "first_delivery_name")
private String firstDeliveryName;
#Column(name = "last_delivery_name")
private String lastDeliveryName;
#Column(name = "delivery_address")
private String deliveryAddress;
#Column
private String status;
#OneToMany(mappedBy = "order", cascade = {
CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE })
private List<OrderItem> orderItems;
#Column(name = "create_date")
private Date createDate;
#Column(name = "update_date")
private Date updateDate;
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getMerchantId() {
return merchantId;
}
public void setMerchantId(long merchantId) {
this.merchantId = merchantId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public String getLastDeliveryName() {
return lastDeliveryName;
}
public void setLastDeliveryName(String lastDeliveryName) {
this.lastDeliveryName = lastDeliveryName;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getFirstDeliveryName() {
return firstDeliveryName;
}
public void setFirstDeliveryName(String firstDeliveryName) {
this.firstDeliveryName = firstDeliveryName;
}
public String getDeliveryAddress() {
return deliveryAddress;
}
public void setDeliveryAddress(String deliveryAddress) {
this.deliveryAddress = deliveryAddress;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
OrderItem.java
package net.township.order;
import com.fasterxml.jackson.annotation.JsonBackReference;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
#Entity
#Table(name = "order_items")
public class OrderItem {
#Id
#GeneratedValue
#Column(name = "id")
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
#Column
private String name;
#Column
private String description;
#Column
private Long quantity;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn (name="ORDER_ID")
#JsonBackReference
#Cascade(value={org.hibernate.annotations.CascadeType.ALL})
private Order order;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
}
When I POST a new Order from my front-end, it is mapped to an Order object correctly. All OrderItems that were provided in the JSON are present in the object as a List as well. However, after I save it to the database using my OrderRepository's save method (it's just a CrudRepository), my database contains a new Order object with the correct fields, but nothing is ever created in ORDER_ITEMS.
I've poked around the documentation for both Hibernate and JPA OneToMany annotations, and I don't see where I'm going wrong here. I'll also add that I'm doing no manual schema creation, letting SpringBoot handle setting up everything in H2 for me.
This is what ultimately worked for me.
Order.java
package net.township.order;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Set;
#Entity
#Table(name = "orders")
public class Order {
public Order() {
}
public Order(long merchantId, String firstDeliveryName, String lastDeliveryName, String deliveryAddress, String status, Date createDate, Date updateDate) {
this.merchantId = merchantId;
this.lastDeliveryName = lastDeliveryName;
this.firstDeliveryName = firstDeliveryName;
this.deliveryAddress = deliveryAddress;
this.status = status;
this.createDate = createDate;
this.updateDate = updateDate;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "order_id", unique = true)
private long orderId;
#Column(name = "merchant_id")
private long merchantId;
#Column(name = "first_delivery_name")
private String firstDeliveryName;
#Column(name = "last_delivery_name")
private String lastDeliveryName;
#Column(name = "delivery_address")
private String deliveryAddress;
#Column
private String status;
#OneToMany( cascade = CascadeType.ALL)
#JoinColumn(name = "order_id", referencedColumnName = "order_id")
private List<OrderItem> orderItems;
#Column(name = "create_date")
private Date createDate;
#Column(name = "update_date")
private Date updateDate;
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getMerchantId() {
return merchantId;
}
public void setMerchantId(long merchantId) {
this.merchantId = merchantId;
}
public List<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public String getLastDeliveryName() {
return lastDeliveryName;
}
public void setLastDeliveryName(String lastDeliveryName) {
this.lastDeliveryName = lastDeliveryName;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getFirstDeliveryName() {
return firstDeliveryName;
}
public void setFirstDeliveryName(String firstDeliveryName) {
this.firstDeliveryName = firstDeliveryName;
}
public String getDeliveryAddress() {
return deliveryAddress;
}
public void setDeliveryAddress(String deliveryAddress) {
this.deliveryAddress = deliveryAddress;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
OrderItem.java
package net.township.order;
import com.fasterxml.jackson.annotation.JsonBackReference;
import javax.persistence.*;
#Entity
#Table(name = "order_items")
public class OrderItem {
#Id
#GeneratedValue
#Column(name = "id")
private Long id;
#Column(name = "order_id")
private Long orderId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column
private String name;
#Column
private String description;
#Column
private Long quantity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getQuantity() {
return quantity;
}
public void setQuantity(Long quantity) {
this.quantity = quantity;
}
}
Add CascadeType.ALL to your mapping.
This is it my database project:
I have a problem with the correct combination of tables, as it is in the picture.
This is my files:
Category.java
#Entity
public class Category {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String categoryName;
protected Category() {}
public Category(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryName() {
return categoryName;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
#Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s']",
id, categoryName);
}
}
Items.java
#Entity
#Table(name = "Items")
public class Items {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int ItemId;
private String ItemName;
private String price;
private Set<Locals> locals = new HashSet<Locals>(0);
public Items(){
}
public Items(String price, String itemName) {
this.price = price;
this.ItemName = itemName;
}
public void setItemId(int itemId) {
ItemId = itemId;
}
public void setLocals(Set<Locals> locals) {
this.locals = locals;
}
public void setPrice(String price) {
this.price = price;
}
public void setItemName(String itemName) {
ItemName = itemName;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "ItemId", unique = true, nullable = false)
public int getItemId() {
return ItemId;
}
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "itemsTo")
public Set<Locals> getLocals() {
return locals;
}
#Column(name = "price", nullable = false, length = 10)
public String getPrice() {
return price;
}
#Column(name = "ItemName", nullable = false, length = 10)
public String getItemName() {
return ItemName;
}
}
Locals.java
#Entity
#Table(name = "Locals")
public class Locals {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int LocalId;
private String localName;
private String address;
private String phoneNumber;
private String coorX;
private String coorY;
private Set<Items> itemsTo = new HashSet<Items>(0);
public Locals(){
}
public Locals(String localName,String address,String phoneNumber, String coorY, String coorX) {
this.coorY = coorY;
this.coorX = coorX;
this.phoneNumber = phoneNumber;
this.address = address;
this.localName = localName;
}
public Locals(String localName,String address,String phoneNumber, String coorY, String coorX, Set<Items> itemsTo) {
this.coorY = coorY;
this.coorX = coorX;
this.phoneNumber = phoneNumber;
this.address = address;
this.localName = localName;
this.itemsTo = itemsTo;
}
public void setLocalId(int localId) {
LocalId = localId;
}
public void setLocalName(String localName) {
this.localName = localName;
}
public void setAddress(String address) {
this.address = address;
}
public void setCoorX(String coorX) {
this.coorX = coorX;
}
public void setCoorY(String coorY) {
this.coorY = coorY;
}
public void setItemsTo(Set<Items> itemsTo) {
this.itemsTo = itemsTo;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "LocalId", unique = true, nullable = false)
public int getLocalId() {
return LocalId;
}
#Column(name = "localName", unique = false, nullable = false, length = 10)
public String getLocalName() {
return localName;
}
#Column(name = "address", unique = false, nullable = false, length = 10)
public String getAddress() {
return address;
}
#Column(name = "phoneNumber", unique = false, nullable = false, length = 10)
public String getPhoneNumber() {
return phoneNumber;
}
#Column(name = "coorX", unique = false, nullable = false, length = 10)
public String getCoorX() {
return coorX;
}
#Column(name = "coorY", unique = false, nullable = false, length = 10)
public String getCoorY() {
return coorY;
}
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "ItemsFinall", joinColumns = {
#JoinColumn(name = "LocalId", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "ItemId",
nullable = false, updatable = false) })
public Set<Items> getItemsTo() {
return itemsTo;
}
}
and ItemsFinall.java
#Entity
#Table(name = "ItemsFinall")
public class ItemsFinall {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private int ItemId;
private int CategoryId;
private int LocalId;
public ItemsFinall(int id, int localId, int categoryId, int itemId) {
this.LocalId = localId;
this.CategoryId = categoryId;
this.ItemId = itemId;
this.id=id;
}
public void setId(int id) {
this.id = id;
}
public void setLocalId(int localId) {
LocalId = localId;
}
public void setCategoryId(int categoryId) {
CategoryId = categoryId;
}
public void setItemId(int itemId) {
ItemId = itemId;
}
public int getLocalId() {
return LocalId;
}
public int getCategoryId() {
return CategoryId;
}
public int getItemId() {
return ItemId;
}
public int getId() {
return id;
}
}
I get the following error: Caused by: org.springframework.data.mapping.PropertyReferenceException: No property categoryName found for type ItemsFinall!
I do not know what to do to properly connect the table.
ItemsServiceImpl.java
package dnfserver.model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Ćukasz on 2015-03-14.
*/
#Component
public class CategoryServiceImpl implements CategoryService {
#Autowired
private CategoryRepository categoryRepository;
private Map<Integer,String> categoryMap = new HashMap<Integer, String>();
#Override
public Category create(Category category) {
Category createdCategory = category;
return categoryRepository.save(createdCategory);
}
#Override
public Category delete(int id) {
return null;
}
#Autowired
public Map<Integer,String> findAll(){
int i=0;
for (Category cat : categoryRepository.findAll()) {
categoryMap.put(i,cat.toString());
i++;
}
return categoryMap;
}
#Override
public Category update(Category shop) {
return null;
}
#Override
public Category findById(int id) {
return categoryRepository.findOne(id);
}
}
In hibernate/JPA you model the relationship between Entities, but not use plain Ids!
For example
#Entity
#Table(name = "ItemsFinall")
public class ItemsFinall {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
//instead of: private int ItemId;
#OneToMany
private Item item;
//instead of: private int CategoryId;
#OneToMany
private Category category;
//instead of: private int LocalId;
#OneToMany
private Local local;
...
(You also need to fix the Set<Locals> locals in item)