我是Java的新手,对Spring(Boot和JPA)更新,但我很好奇,我试图调试一个问题,"没有为实体指定标识符&# 34 ;.
出于Illustartion目的,我已从此图表中创建了以下表格:
最初,用户和车辆表之间存在M:N关系,因此我创建了一个关联实体(UserVehicleAsso)来将两者分开。我在Java,http://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/
上遵循M:N映射的本指南在大多数情况下,它非常简单,但我的问题是,在关联实体(UserVehicleAsso)中,我是否必须为每个外键使用@Id注释?我认为我不需要,因为这些是从每个表中自动生成的。
让我知道你的想法或意见,谢谢。
另外,下面是我用来生成这些模型的代码:
对于User表/类:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
private String fName;
private String lName;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="userVehicleAsso",
joinColumns={@JoinColumn(name="userID")},
inverseJoinColumns={@JoinColumn(name="vehicleID")})
private Set<Vehicle> vehicles = new HashSet<Vehicle>();
//constructor
protected User() {}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getFName() {
return fName;
}
public void setFName(String fName) {
this.fName = fName;
}
public String getLName() {
return lName;
}
public void setLName(String lName) {
this.lName = lName;
}
public Set<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(Set<Vehicle> vehicles) {
this.vehicles = vehicles;
}
@Override
public String toString() {
return getFName() + "," + getLName();
}}
对于Vehicle表/类:
@Entity
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int vehicleId;
private String brand;
private String model;
//foreign key mappings
//mapping with associative
@ManyToMany(mappedBy="vehicles")
private Set<User> users = new HashSet<User>();
//constructors
protected Vehicle() {}
public Vehicle(int id) {
this.vehicleId = id;
}
public Vehicle (String brand, String model) {
this.brand = brand;
this.model = model;
}
/* public Vehicle() {
}*/
public int getVehicleId() {
return vehicleId;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
@Override
public String toString() {
// + setBodyType() + "," +
return getBrand() + "," + getModel();
}
}
最后,我的关联表/类:
@Entity
public class UserVehicleAsso{
private int userID;
private int vehicleID;
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public int getVehicleID() {
return vehicleID;
}
public void setVehicleID(int vehicleID) {
this.vehicleID = vehicleID;
}
}
答案 0 :(得分:1)
在我看来,在你的情况下没有必要为中间表创建一个Entity类。如果配置正确,将自动生成该表。在此表中,不会有列ID
,只有两列包含userID
和vehicleID
数据。
现在,如果你的中间表有超过建立M:N关系所需的中间表,那么你需要你的中间实体类,以及它的ID
。例如,如果此类用于在每次建立关系时存储时间戳,则必须:
ID
字段,JPA / Hibernate的这一部分让我很困惑,而且我过去常常陷入困境。如果我的记忆对我有好处,这就是事情应该如何运作的正确/完美方式。
答案 1 :(得分:0)
您可以指定映射到实体的多个字段或属性的复合主键类。
以下是示例代码:
public class ActivityRegPK implements Serializable {
private int activityId;
private int memberId;
public int getActivityId() {
return activityId;
}
public void setActivityId(int activityId) {
this.activityId = activityId;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
}
关联表/类:
@IdClass(ActivityRegPK.class)
@Entity
@Table(name="activity_reg")
@NamedQuery(name="ActivityReg.findAll", query="SELECT a FROM ActivityReg a")
public class ActivityReg implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="activity_id")
private int activityId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="ins_date")
private Date insDate;
@Id
@Column(name="member_id")
private int memberId;
}
Activity.class
@Entity
@NamedQuery(name="Activity.findAll", query="SELECT a FROM Activity a")
public class Activity implements Serializable {
// some attributes
}