如何使用 Hibernate 注释来持久化双向一对一关系实体?
How to persist Bidirectional one to one relational entities using Hibernate annotations?
我有三个表 Company、Contact 和 Address,在(公司和联系人)和(公司和地址)之间具有双向一对一关系。该关系是通过关系所有者(公司)中的外键。
Company.java
@Entity
@Table(name="company")
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
private int companyId;
private String companyName;
private String paymentTerms;
private Address address;
private Contact contact;
public Company(){ }
public Company(String companyName,String paymentTerms){
this.companyName = companyName;
this.paymentTerms = paymentTerms;
}
@Id
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getPaymentTerms() {
return paymentTerms;
}
public void setPaymentTerms(String paymentTerms) {
this.paymentTerms = paymentTerms;
}
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name="address_addressId",insertable=true,updatable=true,nullable=true,unique=true)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name="contact_contactId",insertable=true,updatable=true,nullable=true,unique=true)
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@Override
public String toString() {
return "Company [companyId=" + companyId + ", companyName="
+ companyName + ", paymentTerms=" + paymentTerms + ", address="
+ address + ", contact=" + contact + "]";
}
}
Contact.java
@Entity
public class Contact {
private int contactId;
private String contactPerson;
private String email;
private String mobileNumber;
private String landlineNumber;
private Company company;
public Contact(){}
@Id
public int getContactId() {
return contactId;
}
public void setContactId(int contactId) {
this.contactId = contactId;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getLandlineNumber() {
return landlineNumber;
}
public void setLandlineNumber(String landlineNumber) {
this.landlineNumber = landlineNumber;
}
@OneToOne(mappedBy="contact")
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
Address.java
@Entity
public class Address {
private int addressId;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String postalCode;
private Company company;
public Address(){}
public Address(String addressLine1,String addressLine2,String city,String state,String postalCode){
this.addressLine1 = addressLine1;
this.addressLine2 = addressLine2;
this.city = city;
this.state = state;
this.postalCode = postalCode;
}
@Id
public int getAddressId() {
return addressId;
}
public void setAddressId(int addressId) {
this.addressId = addressId;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
@OneToOne(mappedBy="address")
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
public void addCompany(Company company,Contact contact,Address address){
try{
emf = Persistence.createEntityManagerFactory("company");
em = emf.createEntityManager();
em.getTransaction().begin();
//address.setAddressId(company.getCompanyId());
company.setAddress(address);
company.setContact(contact);
//contact.setContactId(company.getCompanyId());
em.persist(address);
em.persist(contact);
em.persist(company);
em.getTransaction().commit();
em.close();
}catch(PersistenceException e){
e.printStackTrace();
}
}
我收到错误无法添加或更新子行:外键约束失败 (mydb
.company
, CONSTRAINT fk_company_contact
FOREIGN KEY (contact_contactId
) 参考文献 contact
(contactId
) 删除时无操作更新时无操作)
`Apr 18, 2015 11:24:57 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_25\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Java\jdk1.8.0_25\jre\bin;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/lib/amd64;C:\WINDOWS\system32;C:\Program Files\Java\jdk1.8.0_25\bin;U:\EclipseJEE\eclipse;;.
Apr 18, 2015 11:24:57 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:Struts 2 Portfolio' did not find a matching property.
Apr 18, 2015 11:24:58 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Apr 18, 2015 11:24:58 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1502 ms
Apr 18, 2015 11:24:58 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Apr 18, 2015 11:24:58 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.37
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts-default.xml]
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Unable to locate configuration files of the name struts-plugin.xml, skipping
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts-plugin.xml]
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts.xml]
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.ObjectFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ActionFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ResultFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ConverterFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.InterceptorFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ValidatorFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.UnknownHandlerFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.FileManagerFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.XWorkConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.CollectionConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.ArrayConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.DateConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.NumberConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.StringConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionFileProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.TypeConverterCreator)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.TypeConverterHolder)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.TextProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.LocaleProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.ActionProxyFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ObjectTypeDeterminer)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.mapper.ActionMapper)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (jakarta) for (org.apache.struts2.dispatcher.multipart.MultiPartRequest)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.views.freemarker.FreemarkerManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.components.UrlRenderer)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.validator.ActionValidatorManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.ValueStackFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.reflection.ReflectionProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.reflection.ReflectionContextFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.PatternMatcher)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.StaticContentLoader)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.UnknownHandlerManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.views.util.UrlHelper)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.TextParser)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.DispatcherErrorHandler)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.security.ExcludedPatternsChecker)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.security.AcceptedPatternsChecker)
Apr 18, 2015 11:25:02 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 18, 2015 11:25:02 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Apr 18, 2015 11:25:02 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/68 config=null
Apr 18, 2015 11:25:02 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 4427 ms
Apr 18, 2015 11:25:04 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Login' in namespace: '/authentication'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:05 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Login' in namespace: '/authentication'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:09 AM com.opensymphony.xwork2.interceptor.ParametersInterceptor error
SEVERE: Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'login' on 'class authentication.Authentication: Error setting expression 'login' with value ['Login', ]
Apr 18, 2015 11:25:10 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Logout' in namespace: '/home'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:10 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Logout' in namespace: '/home'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:12 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'add' in namespace: '/company'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:13 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'add' in namespace: '/company'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:29 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
name: company
...]
Apr 18, 2015 11:25:31 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.8.Final}
Apr 18, 2015 11:25:31 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Apr 18, 2015 11:25:31 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Apr 18, 2015 11:25:33 AM org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl processProperties
WARN: HHH000059: Defining hibernate.transaction.flush_before_completion=true ignored in HEM
Apr 18, 2015 11:25:35 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/mydb]
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root}
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Apr 18, 2015 11:25:37 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Apr 18, 2015 11:25:40 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
insert
into
Address
(addressLine1, addressLine2, city, postalCode, state, addressId)
values
(?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
Contact
(contactPerson, email, landlineNumber, mobileNumber, contactId)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
company
(address_addressId, companyName, contact_contactId, paymentTerms, companyId)
values
(?, ?, ?, ?, ?)
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1452, SQLState: 23000
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Cannot add or update a child row: a foreign key constraint fails (`mydb`.`company`, CONSTRAINT `fk_company_contact` FOREIGN KEY (`contact_contactId`) REFERENCES `contact` (`contactId`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1452, SQLState: 23000
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Cannot add or update a child row: a foreign key constraint fails (`mydb`.`company`, CONSTRAINT `fk_company_contact` FOREIGN KEY (`contact_contactId`) REFERENCES `contact` (`contactId`) ON DELETE NO ACTION ON UPDATE NO ACTION)
`
由于实体具有双向关系,您必须在 addCompany
方法中引用它们。这与异常有关:
WARN: Cannot add or update a child row: a foreign key constraint fails
您不使用自动 id 生成,因此您需要在所有实体的 addCompany
方法中明确执行此操作。您可以选择让 Hibernate 为您做这件事,方法是使用 @GeneratedValue
注释 get*Id() 方法并选择合适的 id generation strategy
级联双向关系允许您跳过非拥有方(Contact
和 Address
)实体的显式持久化
多次创建 EntityManagerFactory
会给您的应用程序增加大量开销,应该避免。只需创建一次,让 EntityManager
个实例重用它。
您也可以考虑为 addMethod
的多次调用创建一次 EntityManager
(例如,在 addMethod 的 class 中或通过注入)并仅在不再需要。
将 emf
的初始化移动到其他地方:
emf = Persistence.createEntityManagerFactory("company"); // 4.
addCompany
方法的更新版本:
em = emf.createEntityManager(); // 5.
...
public void addCompany(Company company, Contact contact, Address address) {
em.getTransaction().begin();
company.setAddress(address);
company.setContact(contact);
contact.setCompany(company); // 1.
address.setCompany(company); // 1.
em.persist(company); // 3.
em.getTransaction().commit();
}
...
em.close(); // 5.
我有三个表 Company、Contact 和 Address,在(公司和联系人)和(公司和地址)之间具有双向一对一关系。该关系是通过关系所有者(公司)中的外键。
Company.java
@Entity
@Table(name="company")
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
private int companyId;
private String companyName;
private String paymentTerms;
private Address address;
private Contact contact;
public Company(){ }
public Company(String companyName,String paymentTerms){
this.companyName = companyName;
this.paymentTerms = paymentTerms;
}
@Id
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getPaymentTerms() {
return paymentTerms;
}
public void setPaymentTerms(String paymentTerms) {
this.paymentTerms = paymentTerms;
}
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name="address_addressId",insertable=true,updatable=true,nullable=true,unique=true)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@OneToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name="contact_contactId",insertable=true,updatable=true,nullable=true,unique=true)
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@Override
public String toString() {
return "Company [companyId=" + companyId + ", companyName="
+ companyName + ", paymentTerms=" + paymentTerms + ", address="
+ address + ", contact=" + contact + "]";
}
}
Contact.java
@Entity
public class Contact {
private int contactId;
private String contactPerson;
private String email;
private String mobileNumber;
private String landlineNumber;
private Company company;
public Contact(){}
@Id
public int getContactId() {
return contactId;
}
public void setContactId(int contactId) {
this.contactId = contactId;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getLandlineNumber() {
return landlineNumber;
}
public void setLandlineNumber(String landlineNumber) {
this.landlineNumber = landlineNumber;
}
@OneToOne(mappedBy="contact")
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
Address.java
@Entity
public class Address {
private int addressId;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String postalCode;
private Company company;
public Address(){}
public Address(String addressLine1,String addressLine2,String city,String state,String postalCode){
this.addressLine1 = addressLine1;
this.addressLine2 = addressLine2;
this.city = city;
this.state = state;
this.postalCode = postalCode;
}
@Id
public int getAddressId() {
return addressId;
}
public void setAddressId(int addressId) {
this.addressId = addressId;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
@OneToOne(mappedBy="address")
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
public void addCompany(Company company,Contact contact,Address address){
try{
emf = Persistence.createEntityManagerFactory("company");
em = emf.createEntityManager();
em.getTransaction().begin();
//address.setAddressId(company.getCompanyId());
company.setAddress(address);
company.setContact(contact);
//contact.setContactId(company.getCompanyId());
em.persist(address);
em.persist(contact);
em.persist(company);
em.getTransaction().commit();
em.close();
}catch(PersistenceException e){
e.printStackTrace();
}
}
我收到错误无法添加或更新子行:外键约束失败 (mydb
.company
, CONSTRAINT fk_company_contact
FOREIGN KEY (contact_contactId
) 参考文献 contact
(contactId
) 删除时无操作更新时无操作)
`Apr 18, 2015 11:24:57 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_25\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files\Java\jdk1.8.0_25\jre\bin;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_25/bin/../jre/lib/amd64;C:\WINDOWS\system32;C:\Program Files\Java\jdk1.8.0_25\bin;U:\EclipseJEE\eclipse;;.
Apr 18, 2015 11:24:57 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:Struts 2 Portfolio' did not find a matching property.
Apr 18, 2015 11:24:58 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Apr 18, 2015 11:24:58 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1502 ms
Apr 18, 2015 11:24:58 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Apr 18, 2015 11:24:58 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.37
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts-default.xml]
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Unable to locate configuration files of the name struts-plugin.xml, skipping
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts-plugin.xml]
Apr 18, 2015 11:25:00 AM com.opensymphony.xwork2.config.providers.XmlConfigurationProvider info
INFO: Parsing configuration file [struts.xml]
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.ObjectFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ActionFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ResultFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ConverterFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.InterceptorFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.ValidatorFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.factory.UnknownHandlerFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.FileManagerFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.XWorkConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.CollectionConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.ArrayConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.DateConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.NumberConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.impl.StringConverter)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionFileProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.TypeConverterCreator)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.TypeConverterHolder)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.TextProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.LocaleProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.ActionProxyFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.conversion.ObjectTypeDeterminer)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.mapper.ActionMapper)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (jakarta) for (org.apache.struts2.dispatcher.multipart.MultiPartRequest)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.views.freemarker.FreemarkerManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.components.UrlRenderer)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.validator.ActionValidatorManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.ValueStackFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.reflection.ReflectionProvider)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.reflection.ReflectionContextFactory)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.PatternMatcher)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.StaticContentLoader)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.UnknownHandlerManager)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.views.util.UrlHelper)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.util.TextParser)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (org.apache.struts2.dispatcher.DispatcherErrorHandler)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.security.ExcludedPatternsChecker)
Apr 18, 2015 11:25:00 AM org.apache.struts2.config.AbstractBeanSelectionProvider info
INFO: Choosing bean (struts) for (com.opensymphony.xwork2.security.AcceptedPatternsChecker)
Apr 18, 2015 11:25:02 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Apr 18, 2015 11:25:02 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Apr 18, 2015 11:25:02 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/68 config=null
Apr 18, 2015 11:25:02 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 4427 ms
Apr 18, 2015 11:25:04 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Login' in namespace: '/authentication'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:05 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Login' in namespace: '/authentication'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:09 AM com.opensymphony.xwork2.interceptor.ParametersInterceptor error
SEVERE: Developer Notification (set struts.devMode to false to disable this message):
Unexpected Exception caught setting 'login' on 'class authentication.Authentication: Error setting expression 'login' with value ['Login', ]
Apr 18, 2015 11:25:10 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Logout' in namespace: '/home'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:10 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'Logout' in namespace: '/home'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:12 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'add' in namespace: '/company'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:13 AM org.apache.struts2.components.ServletUrlRenderer warn
WARNING: No configuration found for the specified action: 'add' in namespace: '/company'. Form action defaulting to 'action' attribute's literal value.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:28 AM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Apr 18, 2015 11:25:29 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
name: company
...]
Apr 18, 2015 11:25:31 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.8.Final}
Apr 18, 2015 11:25:31 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Apr 18, 2015 11:25:31 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Apr 18, 2015 11:25:33 AM org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl processProperties
WARN: HHH000059: Defining hibernate.transaction.flush_before_completion=true ignored in HEM
Apr 18, 2015 11:25:35 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/mydb]
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root}
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Apr 18, 2015 11:25:36 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Apr 18, 2015 11:25:37 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Apr 18, 2015 11:25:40 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
insert
into
Address
(addressLine1, addressLine2, city, postalCode, state, addressId)
values
(?, ?, ?, ?, ?, ?)
Hibernate:
insert
into
Contact
(contactPerson, email, landlineNumber, mobileNumber, contactId)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
company
(address_addressId, companyName, contact_contactId, paymentTerms, companyId)
values
(?, ?, ?, ?, ?)
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1452, SQLState: 23000
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Cannot add or update a child row: a foreign key constraint fails (`mydb`.`company`, CONSTRAINT `fk_company_contact` FOREIGN KEY (`contact_contactId`) REFERENCES `contact` (`contactId`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC statements
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: SQL Warning Code: 1452, SQLState: 23000
Apr 18, 2015 11:26:00 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler logWarning
WARN: Cannot add or update a child row: a foreign key constraint fails (`mydb`.`company`, CONSTRAINT `fk_company_contact` FOREIGN KEY (`contact_contactId`) REFERENCES `contact` (`contactId`) ON DELETE NO ACTION ON UPDATE NO ACTION)
`
由于实体具有双向关系,您必须在
addCompany
方法中引用它们。这与异常有关:WARN: Cannot add or update a child row: a foreign key constraint fails
您不使用自动 id 生成,因此您需要在所有实体的
addCompany
方法中明确执行此操作。您可以选择让 Hibernate 为您做这件事,方法是使用@GeneratedValue
注释 get*Id() 方法并选择合适的 id generation strategy级联双向关系允许您跳过非拥有方(
Contact
和Address
)实体的显式持久化多次创建
EntityManagerFactory
会给您的应用程序增加大量开销,应该避免。只需创建一次,让EntityManager
个实例重用它。您也可以考虑为
addMethod
的多次调用创建一次EntityManager
(例如,在 addMethod 的 class 中或通过注入)并仅在不再需要。
将 emf
的初始化移动到其他地方:
emf = Persistence.createEntityManagerFactory("company"); // 4.
addCompany
方法的更新版本:
em = emf.createEntityManager(); // 5.
...
public void addCompany(Company company, Contact contact, Address address) {
em.getTransaction().begin();
company.setAddress(address);
company.setContact(contact);
contact.setCompany(company); // 1.
address.setCompany(company); // 1.
em.persist(company); // 3.
em.getTransaction().commit();
}
...
em.close(); // 5.