2014-03-13 89 views
1

我正在使用java使用基本的mySQL关系数据库。我附加了两个具有1:M关系的表的实体类。我已经定义了1是许多和许多是在实体表中的1个关系。在Projects类中,我想声明外键(private int contractor_id)以及getter和setter(如注释所示),但我一直得到编译错误,指出以下内容*字段[项目存在多个可写映射。 contractor_id。只有一个可以被定义为可写,所有其他都必须被指定为只读。*因此,我们将它们的值注释掉,因为它们的值已经在BusinessAccount类中设置。数据现在使用我已经显示的'addProject()'方法持久化到数据库。但是,字段contractor_id(即外键)作为null传递给Projects表。我为会话(名为sessionContractorId)的会话的值为contractor_id,但我无法将其传递到数据库,因为我没有为此表设置setter。有关如何将外键的值保存到数据库的建议,我们将不胜感激。为什么外键数据不会持久到mysql数据库?

@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"; 
    } 
+0

'projects'来自'addProject'方法的地方在哪里? –

+0

道歉 - 我试图减少发布的代码量,错过了未显示项目源的代码。我现在更新了代码。谢谢 – kellzer

回答

1

有两件事情,我注意到有关的代码。

首先,代码应该与实体一起工作,并忽略特定实体的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(不确定其来源)是否被持久化。假设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我上的双向创建一个对许多关系。

+0

感谢您的帮助 - 我现在有工作! – kellzer

+0

@NiallKelly很高兴听到这个,很棒的工作! –