2014-03-13 91 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很高興聽到這個,很棒的工作! –