我是Spring Data JPA和CRUD存储库的新手。如果我保存每个单独的实体,我有可以保存到数据库的代码,但我认为我应该能够保存父实体并自动保存或更新包含的子实体。我做错了吗?
执行保存的代码:
private static CustomerRepository customerRepository;
@Transactional
public ResultCreateCustomer addCustomer(NameTable nameIn, Address addressIn)
throws Exception {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
customerRepository = context.getBean(CustomerRepository.class);
ResultCreateCustomer result = new ResultCreateCustomer(0, 0, 0, DATABASE_OR_SYSTEM_ERROR);
try {
NameTable theName = new NameTable();
theName.setFirstName(nameIn.getFirstName());
theName.setLastName(nameIn.getLastName());
Address theAddress = new Address();
theAddress.setStreetNo(addressIn.getStreetNo());
theAddress.setStreetName(addressIn.getStreetName());
theAddress.setCityStateZip(addressIn.getCityStateZip());
Customer theCustomer = new Customer();
theCustomer.setNameTable(theName);
theCustomer.setAddress(theAddress);
customerRepository.save(theCustomer);
} catch (Exception e) {
this.log.error("got exception: " + e.getClass() + ": " + e.getMessage());
}
context.close();
return result;
}
客户实体的代码:
@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="Customer")
public class Customer implements Serializable {
public Customer() {
}
@Column(name="ID", nullable=false, unique=true)
@Id
@GeneratedValue(generator="COM_COMPORIUM_CUSTOMER_DOMAIN_CUSTOMER_ID_GENERATOR")
@org.hibernate.annotations.GenericGenerator(name="COM_COMPORIUM_CUSTOMER_DOMAIN_CUSTOMER_ID_GENERATOR", strategy="native")
private int ID;
@ManyToOne(targetEntity=com.comporium.customer.addresses.Address.class, fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="AddressID", referencedColumnName="ID") })
private com.comporium.customer.addresses.Address address;
@OneToOne(targetEntity=com.comporium.customer.contactrolodex.NameTable.class, fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="NameTableID", nullable=false) })
private com.comporium.customer.contactrolodex.NameTable nameTable;
@Column(name="IndustryCode", nullable=false)
private int industryCode;
@Column(name="DemographicCode", nullable=false)
private int demographicCode;
@Column(name="Ranking", nullable=false)
private int ranking;
public void setNameTable(com.comporium.customer.contactrolodex.NameTable value) {
this.nameTable = value;
}
public com.comporium.customer.contactrolodex.NameTable getNameTable() {
return nameTable;
}
// Other setters and getters follow
}
第一个子类的代码:
@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="NameTable")
public class NameTable implements Serializable {
public NameTable() {
}
@Column(name="ID", nullable=false, unique=true)
@Id
@GeneratedValue(generator="COM_COMPORIUM_CUSTOMER_CONTACTROLODEX_NAMETABLE_ID_GENERATOR")
@org.hibernate.annotations.GenericGenerator(name="COM_COMPORIUM_CUSTOMER_CONTACTROLODEX_NAMETABLE_ID_GENERATOR", strategy="native")
private int ID;
@Column(name="FirstName", nullable=true, length=30)
private String firstName;
@Column(name="LastName", nullable=true, length=40)
private String lastName;
@OneToOne(mappedBy="nameTable", targetEntity=com.comporium.customer.domain.Customer.class, fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
private com.comporium.customer.domain.Customer customer;
}
存储库接口CustomerRepository:
package com.comporium.customer.repositories;
import org.springframework.data.repository.CrudRepository;
import com.comporium.customer.domain.Customer;
public interface CustomerRepository extends CrudRepository<Customer, Integer> {
}
当我运行可执行文件(通过SOAP调用)时,我得到一个例外:
2014-11-19 09:57:59,253 ERROR VPcodeDao:306 - got exception: class org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.comporium.customer.domain.Customer.nameTable -> com.comporium.customer.contactrolodex.NameTable; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.comporium.customer.domain.Customer.nameTable -> com.comporium.customer.contactrolodex.NameTable
还有一种方法可以让save(theCustomer)保存包含的子实体吗?
答案 0 :(得分:0)
不确定是否可以找到解决方案。但是解决方案是定义级联
@OneToOne(cascade = {CascadeType.ALL}, mappedBy="nameTable", targetEntity=com.comporium.customer.domain.Customer.class, fetch=FetchType.LAZY)