gpt4 book ai didi

java - 为什么外键数据不会持久化到mysql数据库?

转载 作者:行者123 更新时间:2023-11-29 00:17:39 24 4
gpt4 key购买 nike

我正在使用 java 处理基本的 mySQL 关系数据库。我已经为具有 1:M 关系的两个表附加了实体类。我在实体表中定义了 1 对多和多对 1 的关系。在 Projects 类中,我想声明外键(private int contractor_id)以及 getter 和 setter(如注释掉的所示),但我不断收到编译错误,指出以下 *Multiple writable mappings exist for the field [projects. contractor_id]。只有一个可以定义为可写,所有其他必须指定为只读。* 因此我将它们注释掉,因为它们的值已经在 BusinessAccount 类中设置。数据现在使用我展示的“addProject()”方法保存到数据库中。但是,字段 contractor_id(即外键)作为空值传递给 Projects 表。我有一个 session 的 contractor_id 值(名为 sessionContractorId),但我无法将它传递给数据库,因为我没有此表的 setter 。关于如何将外键值保存到数据库的任何建议将不胜感激?

@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 中,您负责管理关联的双方。所以你必须添加 AccountProject在关系的另一边设置 Project对于 Account .我从未在代码中看到这种情况,我只看到 projects (不确定其来源)被坚持。假设 projectsList<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>();

希望这会解决您的问题,我建议您观看此 video tutorial我创建了双向一对多关系。

关于java - 为什么外键数据不会持久化到mysql数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22366795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com