![](/img/trans.png)
[英]Unable to persist data into mysql database using spring + spring data jpa, Why?
[英]Why will foreign key data will not persist to mysql database?
我正在使用Java使用基本的mySQL關系數據庫。 我已為具有1:M關系的兩個表附加了實體類。 我已經在實體表中定義了“ 1對很多”關系。 在Projects類中,我想同時聲明外鍵(私有int contractor_id)以及getter和setter(如注釋所示),但是我不斷收到編譯錯誤,指出以下內容*項目[field.projects.com.cn]存在多個可寫映射。 contractor_id。 只能將其中一個定義為可寫,所有其他都必須指定為只讀。*因此,由於在BusinessAccount類中已經設置了它們的值,因此我將它們注釋掉。 現在,已使用我顯示的“ addProject()”方法將數據持久保存到數據庫中。 但是,字段contractor_id(即外鍵)作為null傳遞給Projects表。 我有一個用於會話的contractor_id的值(名為sessionContractorId),但由於沒有此表的設置程序,因此無法將其傳遞給數據庫。 關於如何將數據庫外鍵的值持久化的任何建議將不勝感激。
@Entity
@Table(name = "business_accounts")
public class BusinessAccount {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "surname")
private String surname;
@OneToMany(mappedBy = "businessAccount", fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
private List<Projects> projects;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public List<Projects> getProjects()
{
if (projects == null)
{
projects = new ArrayList<Projects>();
}
return projects;
}
public void setProjects(List<Projects> projects)
{
this.projects = projects;
}
}
@Entity
@Table(name = "projects")
public class Projects {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int project_id;
@Column(name = "project_name")
private String projectName;
@Column(name = "project_description")
private String projectDescription;
//@Column(name = "contractor_id")
//private int contractorId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({ @JoinColumn(name = "contractor_id", referencedColumnName="id") })
private BusinessAccount businessAccount;
public BusinessAccount getBusinessAccount() {
if (businessAccount == null) {
businessAccount = new BusinessAccount();
}
return businessAccount;
}
public void setBusinessAccount(BusinessAccount businessAccount) {
this.businessAccount = businessAccount;
}
public int getProject_id() {
return project_id;
}
public void setProject_id(int project_id) {
this.project_id = project_id;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getProjectDescription() {
return projectDescription;
}
public void setProjectDescription(String projectDescription) {
this.projectDescription = projectDescription;
}
//public int getContractorId() {
//return contractorId;
//}
//public void setContractorId(int contractorId) {
//this.contractorId = contractorId;
//}
}
@ManagedBean
@ViewScoped
public class ProjectBean implements Serializable {
private static final long serialVersionUID = -2107387060867715013L;
private static final String PERSISTENCE_UNIT_NAME = "NeedABuilderUnit";
private static EntityManagerFactory factory;
private Projects projects;
private List<BusinessAccount> businessAccount;
public ProjectBean() {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
List<BusinessAccount> businessAccount = em.createQuery("from BusinessAccount a", BusinessAccount.class)
.getResultList();
em.close();
setBusinessAccount(businessAccount);
}
@PostConstruct
public void init() {
projects = new Projects();
}
public String addProject() {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
String sessionEmail=Util.getEmail();
Query myQuery = em.createQuery("SELECT u FROM BusinessAccount u WHERE u.email=:email");
myQuery.setParameter("email", sessionEmail);
List<BusinessAccount> accounts=myQuery.getResultList();
int sessionContractorId=accounts.get(0).getId();
em.persist(projects);
em.getTransaction().commit();
em.close();
return "success";
}
我注意到有關代碼的兩件事。
首先,代碼應使用實體,並忽略特定實體的id
字段。 因此,當您提取帳戶時,它應該獲取實體而不是ID:
//Don't do this
List<BusinessAccount> accounts=myQuery.getResultList();
int sessionContractorId=accounts.get(0).getId();
//Instead do this
List<BusinessAccount> accounts=myQuery.getResultList();
BusinessAccount account =accounts.get(0); //hopefully an account exists
其次,在JPA中,您負責管理關聯雙方。 因此,您必須將Account
添加到Project
並在關系的另一側為Account
設置Project
。 我從沒在代碼中看到這種情況,僅看到持久化的projects
(不確定其來源)。 假設projects
是一個List<Project>
,它將看起來像這樣:
public String addProject() {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
String sessionEmail=Util.getEmail();
Query myQuery = em.createQuery("SELECT u FROM BusinessAccount u WHERE u.email=:email");
myQuery.setParameter("email", sessionEmail);
List<BusinessAccount> accounts=myQuery.getResultList();
BusinessAccount account =accounts.get(0);
projects.setBusinessAccount(account); //managing both sides
account.getProjects().add(projects); //managing both sides
em.persist(projects);
em.getTransaction().commit();
em.close();
return "success";
}
附帶說明一下,您可能希望將類名更改為Project
並使用變量名project
因為它可以更准確地描述關系。 同樣,由於您正在創建一個新Project
您將需要實例化List<BusinessAccount>
:
List<BusinessAccount> projects = new ArrayList<BusinessAccount>();
希望這能解決您的問題,我建議您觀看我在雙向一對多關系上創建的此視頻教程 。
您應該使用@JoinColumn(name="id_user", insertable = false, updatable = false)
請參考: JPA中的多個可寫映射?
希望這可以幫助 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.