我正在使用 Springboot 和 JPA 創建兩個共享相同主鍵的表。
對于我寫的第一張表:
public class UserAccount implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy ="user", cascade = {CascadeType.REMOVE, CascadeType.MERGE,
CascadeType.REFRESH}, fetch=FetchType.LAZY)
@PrimaryKeyJoinColumn
private UserLogin login;
}
對于我寫的第二張表:
public class UserLogin implements Serializable
{
@Id
private Long user_id;
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
@MapsId("user_id")
@JoinColumn(name = "user_id", referencedColumnName = "id")
@Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user)
{
this.user = user;
this.user_id = user.getId();
}
}
為簡潔起見,省略了其他內容。該代碼有效,因為我通過撰寫陳述句手動設定了 UserLogin 的 id
this.user_id = user.getId();
否則我得到錯誤:
休眠錯誤:必須在呼叫 save() 之前手動分配此類的 id:
我想可以手動管理 id,但我無法獲得正確的配置。
更新:我找到了解決方案,謝謝(請參閱接受的答案)。現在我只是在設定用戶登錄時擺脫 findById() 。
//these methods are defined within a dedicated @Service
@Transactional
public void createLoginInfo(UserAccount user)
{
UserLogin userlogin=new UserLogin();
this.addLoginToUser(userlogin,user);
loginService.save(userlogin);
}
@Transactional
public void addLoginToUser(UserLogin login, UserAccount account)
{
//whit this commented line works
//UserAccount acc= this.findById(account.getId());
login.setUser(account);
account.setLogin(login);
}
//In a transactional test method I first create the user then I call
userService.save(theuser);
userService.createLoginInfo(theuser);
uj5u.com熱心網友回復:
您有一個雙向關系,但已將它與一些不能很好地協同作業的競爭選項映射。首先,在 UserAccount 中,不清楚為什么要生成一個 ID,但還要嘗試將它與關系映射(特別是使用 PrimaryKeyJoinColumn)。如果您希望生成它,它也不能是參考中的外鍵值 - 并且您已經通過“mappedBy”設定將此關系設定為“另一端”。它應該只是:
public class UserAccount implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy ="user", cascade = {CascadeType.REMOVE, CascadeType.MERGE,
CascadeType.REFRESH}, fetch=FetchType.LAZY)
private UserLogin login;
}
用戶登錄應該只是:
public class UserLogin implements Serializable {
@Id
private Long user_id;
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
@MapsId("user_id")
@JoinColumn(name = "user_id", referencedColumnName = "id")
@Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user) {
this.user = user;
}
}
請注意,因為您在用戶關系上有 mapsId 注釋,所以一旦分配了 ID,JPA 將為您設定 user_id 屬性 - 無需自己手動設定。你可以,但如果你這樣做,你必須確保它是以前分配的——這需要在用戶帳戶上保存/重繪 。如果您實際上不使用 Long user_id 屬性,您甚至不需要映射它;您可以將用戶屬性標記為 ID:
public class UserLogin implements Serializable {
@Id
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH},
fetch=FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "id")
@Setter(AccessLevel.NONE)
private UserAccount user;
public void setUser(UserAccount user) {
this.user = user;
}
}
然后,來自 UserAccount 的 Long ID 可用于查找 UesrAccounts 和 UserLogin 實體。
uj5u.com熱心網友回復:
嘗試這個 :
public class UserLogin implements Serializable
{
@Id
private Long user_id;
@OneToOne(fetch=FetchType.LAZY)
@MapsId
@JoinColumn(name = "user_id")
private UserAccount user;
public UserAccount getUser() {
return user;
}
public void setUser(UserAccount user) {
this.user = user;
}
}
public class UserAccount implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
持久化 UserLogin :
EntityManager em;
UserAccount user = em.find(UserAccount.class, 1L)
UserLogin login = new UserLogin();
login.setUser(user);
em.persist(login);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/531577.html
下一篇:502BadgatewayNginxreversyproxy,connect()failed(111:Connectionrefused)同時連接到上游
