2016-11-03 79 views
0

我是Java新手,對Spring更新(引導和JPA)更新,但我很好奇,我試圖調試一個問題:「沒有爲實體指定標識符」。Spring JPA - 數據完整性關係

對於illustartion目的,我創建從該圖中,下表中:

enter image description here

最初,有一個M:N用戶和車輛臺之間的關係,所以我創建一個關聯實體(UserVehicleAsso)將它們分開。我正在關注Java中M:N映射的指南,http://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/

大多數情況下,它非常簡單,但我的問題是,在關聯實體(UserVehicleAsso)中,是否必須使用@Id註釋對於每個外鍵?我假設我不需要,因爲那些是從每個相應的表中自動生成的。

讓我知道你的想法或意見,謝謝。

另外,下面是我用來生成這些模型的代碼:

對於用戶表/類:

@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(); 
}} 

用於車輛表/類:

@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; 
} 


} 
+2

你不應該有這種UserVehicleAsso實體。 – Snickers3192

+0

你們是對的,非常感謝你! – rj2700

回答

1

在我看來,你的情況沒有必要有一箇中間表的實體類。如果配置正確,該表將自動生成。在此表中,不會有列ID,只有兩列與userIDvehicleID數據。

現在,如果你的中間表有比建立M:N關係所需要的更多的東西,那麼你的中間實體類是需要的,並且它也是它的ID。例如,如果這個類是爲了每次建立關係時存儲的時間戳記,您必須:

  1. 創建這個實體類,
  2. 給它適當產生戰略的ID場,
  3. 將時間戳與具有適當類型的字段,註釋/ XML映射等進行映射。

JPA/Hibernate的這部分讓我感到困惑,並且我經常陷入困境。如果我的記憶爲我服務,這是適當/完美的方式應該如何工作。

+0

我很感謝你的回答,但我認爲我應該改進這個問題來解決具體問題。無論如何,我同意你的第二點 - 我還要補充說,如果你的數據庫設計擴展了(即 - 另一個M:N關係被添加到這個連接點),那麼這些關聯實體可以用來適應這種關係。 – rj2700

+0

我很抱歉,你完全正確!那麼假設Spring將在實現它時創建該關聯實體表是安全的嗎? – rj2700

+1

不是Spring,但是當第一次建立關係時,如果一切正常,Hibernate/JPA會創建它。這是預期的行爲。 – FaithReaper

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; 
    } 
} 

associtive表/類:

@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 
}