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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.