我在 Netbeans 中设置 Java 持久性时出错。我使用 MySQL 作为后端数据库服务器。
我的代码如下,
数据库
CREATE TABLE `hub` (
`hub_ID` INT(11) NOT NULL AUTO_INCREMENT,
`hub_Name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`hub_ID`),
UNIQUE INDEX `hub_Name` (`hub_Name`)
)ENGINE=MyISAM
CREATE TABLE `company` (
`company_ID` INT(11) NOT NULL AUTO_INCREMENT,
`company_Name` VARCHAR(45) NOT NULL,
`company_hub_ID` INT(11) NOT NULL,
PRIMARY KEY (`company_ID`),
INDEX `fk_company_hub1` (`company_hub_ID`)
)
Persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="testJPAPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>testjpa.Hub</class>
<class>testjpa.Company</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/logistikumdispatch"/>
<property name="javax.persistence.jdbc.password" value="rootroot"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
</properties>
</persistence-unit>
</persistence>
Hub.java(项目中的实体类)
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package testjpa;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
*
* @author Anjum
*/
@Entity
@Table(name = "hub")
@NamedQueries({
@NamedQuery(name = "Hub.findAll", query = "SELECT h FROM Hub h"),
@NamedQuery(name = "Hub.findByHubID", query = "SELECT h FROM Hub h WHERE h.hubID = :hubID"),
@NamedQuery(name = "Hub.findByHubName", query = "SELECT h FROM Hub h WHERE h.hubName = :hubName")})
public class Hub implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "hub_ID")
private Integer hubID;
@Basic(optional = false)
@Column(name = "hub_Name")
private String hubName;
@OneToMany(mappedBy="hub", cascade=CascadeType.ALL)
@JoinColumn(name="company_hub_ID")
private Collection<Company> companies;
public Hub() {
}
public Hub(Integer hubID) {
this.hubID = hubID;
}
public Hub(Integer hubID, String hubName) {
this.hubID = hubID;
this.hubName = hubName;
}
public Integer getHubID() {
return hubID;
}
public void setHubID(Integer hubID) {
this.hubID = hubID;
}
public String getHubName() {
return hubName;
}
public void setHubName(String hubName) {
this.hubName = hubName;
}
public Collection<Company> getCompanies()
{
return companies;
}
public void setCompanies(Collection<Company> companies)
{
this.companies = companies;
}
@Override
public int hashCode() {
int hash = 0;
hash += (hubID != null ? hubID.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Hub)) {
return false;
}
Hub other = (Hub) object;
if ((this.hubID == null && other.hubID != null) || (this.hubID != null && !this.hubID.equals(other.hubID))) {
return false;
}
return true;
}
@Override
public String toString() {
return "testjpa.Hub[hubID=" + hubID + "]";
}
}
Company.java(项目中的实体类)
package testjpa;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
*
* @author Anjum
*/
@Entity
@Table(name = "company")
@NamedQueries({
@NamedQuery(name = "Company.findAll", query = "SELECT c FROM Company c"),
@NamedQuery(name = "Company.findByCompanyID", query = "SELECT c FROM Company c WHERE c.companyID = :companyID"),
@NamedQuery(name = "Company.findByCompanyName", query = "SELECT c FROM Company c WHERE c.companyName = :companyName"),
@NamedQuery(name = "Company.findByCompanyhubID", query = "SELECT c FROM Company c WHERE c.companyhubID = :companyhubID")})
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "company_ID")
private Integer companyID;
@Basic(optional = false)
@Column(name = "company_Name")
private String companyName;
@Basic(optional = false)
@Column(name = "company_hub_ID")
private int companyhubID;
@ManyToOne()
@JoinColumn(name="hub_ID", insertable=false, updatable=false)
private Hub hub;
public Company() {
}
public Company(Integer companyID) {
this.companyID = companyID;
}
public Company(Integer companyID, String companyName, int companyhubID) {
this.companyID = companyID;
this.companyName = companyName;
this.companyhubID = companyhubID;
}
public Integer getCompanyID() {
return companyID;
}
public void setCompanyID(Integer companyID) {
this.companyID = companyID;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public int getCompanyhubID() {
return companyhubID;
}
public void setCompanyhubID(int companyhubID) {
this.companyhubID = companyhubID;
}
public Hub getHub()
{
return hub;
}
public void setHub(Hub hub)
{
this.hub = hub;
}
@Override
public int hashCode() {
int hash = 0;
hash += (companyID != null ? companyID.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Company)) {
return false;
}
Company other = (Company) object;
if ((this.companyID == null && other.companyID != null) || (this.companyID != null && !this.companyID.equals(other.companyID))) {
return false;
}
return true;
}
@Override
public String toString() {
return "testjpa.Company[companyID=" + companyID + "]";
}
}
主程序
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package testjpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
/**
*
* @author Anjum
*/
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("testJPAPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Company c1 = new Company();
c1.setCompanyName("ays");
Hub h1 = new Hub();
h1.setHubName("abc");
em.persist(h1);
c1.setHub(h1);
em.persist(c1);
em.flush();
}
}
输出
[EL Info]: 2010-09-03 14:39:02.639--ServerSession(3199106)--EclipseLink, version: Eclipse Persistence Services - 2.0.2.v20100323-r6872
[EL Info]: 2010-09-03 14:39:03.371--ServerSession(3199106)--file:/C:/Users/Anjum/Documents/NetBeansProjects/testJPA/build/classes/_testJPAPU login successful
问题
我的问题是,外键 company.company_hub_ID 在数据库中更新为 comapany.company_name = "ays"。但是 company.company_hub_ID 中始终为 0。
Hub 也已正确更新。意味着没有连接或 JPA 问题。问题仅出在关系中。
在此先感谢您对我的帮助。
最佳答案
如前所述,您不应在 OneToMany/ManyToOne 关联的两侧使用 JoinColumn
,而只能在拥有方(多方)使用。从 OneToMany
端删除它并修复列名。
你也不应该在 Company
实体中有一个 companyhubID
属性来保存外键(这些东西实际上应该隐藏在对象级别).从 JoinColumn
中删除属性和 insertable=false, updatable=false
。
所以映射应该是:
@Entity
...
public class Hub implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "hub_ID")
private Integer hubID;
@Basic(optional = false)
@Column(name = "hub_Name")
private String hubName;
<b>@OneToMany(mappedBy="hub", cascade=CascadeType.ALL)
// @JoinColumn(name="company_hub_ID") // THIS IS WRONG
private Collection companies = new HashSet()</b>
...
// method to set both sides of the link of the bidirectional association
public void addToCompanies(Company company) {
company.setHub(this);
this.companies.add(company);
}
}
和
@Entity
...
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "company_ID")
private Integer companyID;
@Basic(optional = false)
@Column(name = "company_Name")
private String companyName;
<b>// @Basic(optional = false)
// @Column(name = "company_hub_ID")
// private int companyhubID; // NO, DON'T
@ManyToOne()
@JoinColumn(name="company_hub_ID"/*, insertable=false, updatable=false*/)
private Hub hub;</b>
...
}
一些补充说明:
- 使用
IDENTITY
策略生成 ID 没问题。 - 您应该使用 InnoDB 表来实现参照完整性。
另请注意,您的演示代码不正确,您没有正确设置关联。应该是:
Company c1 = new Company();
c1.setCompanyName("ays");
Hub h1 = new Hub();
h1.setHubName("abc");
h1.addToCompanies.add(c1); // set the bidirectional association
em.persist(h1); // JPA will cascade the persist
em.flush();
关于java - Netbeans 6.9.1 的 Java Persistence API 中的外键问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3634468/