我在基于Spring 4.3.1的Web应用程序中使用了hibernate 4.3.11。我有三个实体,即CostSheetEntity,RawMaterialEntity和LaborEntity。
CostSheetEntity由多个RawMaterialEntity和LaborEntity组成。并且一个RawMaterialEntity或LaborEntity可以属于多个CostSheetEntity。
为了处理这些关系,我创建了由两个名为CostSheetRawMaterialMapEntity和CostSheetLaborMapEntity的映射实体表示的映射表。这些映射表/实体还带有额外的字段,以便在成本单中保存额外的数据,如特定原材料和人工的费率和消耗。
问题陈述:我必须保存CostSheetEntity。当我尝试这样做时,只保存CostSheetEntity。相应的映射实体CostSheetRawMaterialMapEntity和CostSheetLaborMapEntity不会保存到数据库中(MySQL 5.7)。
我在做什么。以下是我的实体类代码。
CostSheetEntity
@Entity
@Table(name = "jak_md_cost_sheet", catalog = "jakerp", uniqueConstraints = @UniqueConstraint(columnNames = "COST_SHEET_NAME"))
public class CostSheetEntity implements java.io.Serializable {
private static final long serialVersionUID = -3249250828933375991L;
private Integer id;
private BuyerEntity buyerEntity;
private EmployeeEntity employeeEntity;
private ProductCategoryEntity productCategoryEntity;
private String costSheetName;
private String description;
private Set<CostSheetLaborMapEntity> costSheetLaborMapEntities = new HashSet<CostSheetLaborMapEntity>(0);
private Set<CostSheetRawMaterialMapEntity> costSheetRawMaterialMapEntities = new HashSet<CostSheetRawMaterialMapEntity>(0);
private Set<StyleEntity> styleEntities = new HashSet<StyleEntity>(0);
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "BUYER_ID")
public BuyerEntity getBuyerEntity() {
return this.buyerEntity;
}
public void setBuyerEntity(BuyerEntity buyerEntity) {
this.buyerEntity = buyerEntity;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MERCHANT_ID")
public EmployeeEntity getEmployeeEntity() {
return this.employeeEntity;
}
public void setEmployeeEntity(EmployeeEntity employeeEntity) {
this.employeeEntity = employeeEntity;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PRODUCT_CATEGORY", nullable = false)
public ProductCategoryEntity getProductCategoryEntity() {
return this.productCategoryEntity;
}
public void setProductCategoryEntity(ProductCategoryEntity productCategoryEntity) {
this.productCategoryEntity = productCategoryEntity;
}
@Column(name = "COST_SHEET_NAME", unique = true, nullable = false, length = 100)
public String getCostSheetName() {
return this.costSheetName;
}
public void setCostSheetName(String costSheetName) {
this.costSheetName = costSheetName;
}
@Column(name = "DESCRIPTION", length = 500)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "costSheetEntity")
public Set<CostSheetLaborMapEntity> getCostSheetLaborMapEntities() {
return this.costSheetLaborMapEntities;
}
public void setCostSheetLaborMapEntities(Set<CostSheetLaborMapEntity> costSheetLaborMapEntities) {
this.costSheetLaborMapEntities = costSheetLaborMapEntities;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "costSheetEntity")
public Set<CostSheetRawMaterialMapEntity> getCostSheetRawMaterialMapEntities() {
return this.costSheetRawMaterialMapEntities;
}
public void setCostSheetRawMaterialMapEntities(Set<CostSheetRawMaterialMapEntity> costSheetRawMaterialMapEntities) {
this.costSheetRawMaterialMapEntities = costSheetRawMaterialMapEntities;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "costSheetEntity")
public Set<StyleEntity> getStyleEntities() {
return this.styleEntities;
}
public void setStyleEntities(Set<StyleEntity> styleEntities) {
this.styleEntities = styleEntities;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
RawMaterialEntity
@Entity
@Table(name = "jak_md_raw_material", catalog = "jakerp", uniqueConstraints = @UniqueConstraint(columnNames = "MATERIAL_NAME"))
public class RawMaterialEntity implements java.io.Serializable {
private static final long serialVersionUID = 3037539645227982760L;
private Integer id;
private RawMaterialCategoryEntity rawMaterialCategoryEntity;
private UnitOfMeasureEntity unitOfMeasureEntityByUnitGeneral;
private UnitOfMeasureEntity unitOfMeasureEntityByUnitThickness;
private String materialName;
private String description;
private Set<CostSheetRawMaterialMapEntity> costSheetRawMaterialMapEntities = new HashSet<CostSheetRawMaterialMapEntity>(
0);
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "RAW_MATERIAL_CATEGORY_ID", nullable = false)
public RawMaterialCategoryEntity getRawMaterialCategoryEntity() {
return this.rawMaterialCategoryEntity;
}
public void setRawMaterialCategoryEntity(RawMaterialCategoryEntity rawMaterialCategoryEntity) {
this.rawMaterialCategoryEntity = rawMaterialCategoryEntity;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "UNIT_GENERAL")
public UnitOfMeasureEntity getUnitOfMeasureEntityByUnitGeneral() {
return this.unitOfMeasureEntityByUnitGeneral;
}
public void setUnitOfMeasureEntityByUnitGeneral(UnitOfMeasureEntity unitOfMeasureEntityByUnitGeneral) {
this.unitOfMeasureEntityByUnitGeneral = unitOfMeasureEntityByUnitGeneral;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "UNIT_THICKNESS")
public UnitOfMeasureEntity getUnitOfMeasureEntityByUnitThickness() {
return this.unitOfMeasureEntityByUnitThickness;
}
public void setUnitOfMeasureEntityByUnitThickness(UnitOfMeasureEntity unitOfMeasureEntityByUnitThickness) {
this.unitOfMeasureEntityByUnitThickness = unitOfMeasureEntityByUnitThickness;
}
@Column(name = "MATERIAL_NAME", unique = true, nullable = false, length = 100)
public String getMaterialName() {
return this.materialName;
}
public void setMaterialName(String materialName) {
this.materialName = materialName;
}
@Column(name = "DESCRIPTION", length = 500)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
@OneToMany(mappedBy = "rawMaterialEntity")
public Set<CostSheetRawMaterialMapEntity> getCostSheetRawMaterialMapEntities() {
return this.costSheetRawMaterialMapEntities;
}
public void setCostSheetRawMaterialMapEntities(Set<CostSheetRawMaterialMapEntity> costSheetRawMaterialMapEntities) {
this.costSheetRawMaterialMapEntities = costSheetRawMaterialMapEntities;
}
}
CostSheetRawMaterialMapEntity
@Entity
@Table(name = "jak_md_cost_sheet-raw_material", catalog = "jakerp")
public class CostSheetRawMaterialMapEntity implements java.io.Serializable {
private Integer id;
private CostSheetEntity costSheetEntity;
private RawMaterialEntity rawMaterialEntity;
private BigDecimal consumption;
private BigDecimal rate;
private BigDecimal lineTotal;
public CostSheetRawMaterialMapEntity() {
}
public CostSheetRawMaterialMapEntity(CostSheetEntity costSheetEntity, RawMaterialEntity rawMaterialEntity,
BigDecimal consumption, BigDecimal rate, BigDecimal lineTotal) {
this.costSheetEntity = costSheetEntity;
this.rawMaterialEntity = rawMaterialEntity;
this.consumption = consumption;
this.rate = rate;
this.lineTotal = lineTotal;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "COST_SHEET_ID", nullable = false)
public CostSheetEntity getCostSheetEntity() {
return this.costSheetEntity;
}
public void setCostSheetEntity(CostSheetEntity costSheetEntity) {
this.costSheetEntity = costSheetEntity;
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "RAW_MATERIAL_ID", nullable = false)
public RawMaterialEntity getRawMaterialEntity() {
return this.rawMaterialEntity;
}
public void setRawMaterialEntity(RawMaterialEntity rawMaterialEntity) {
this.rawMaterialEntity = rawMaterialEntity;
}
@Column(name = "CONSUMPTION", nullable = false, precision = 10)
public BigDecimal getConsumption() {
return this.consumption;
}
public void setConsumption(BigDecimal consumption) {
this.consumption = consumption;
}
@Column(name = "RATE", nullable = false, precision = 10)
public BigDecimal getRate() {
return this.rate;
}
public void setRate(BigDecimal rate) {
this.rate = rate;
}
@Column(name = "LINE_TOTAL", nullable = false, precision = 10)
public BigDecimal getLineTotal() {
return this.lineTotal;
}
public void setLineTotal(BigDecimal lineTotal) {
this.lineTotal = lineTotal;
}
}
与原材料实体类似,也存在劳动实体。当要保存CostSheetEntity时,这两个子实体也应该插入和/或更新到数据库中。
我与数据库交互的方式是使用DAO,而DAO又使用以下DBUtil类来执行实际的数据库操作:
/**
* The Class HibernateUtil. This class is a wrapper on Hibernate methods to perform CRUD operations with Entities
*/
@Repository
public class HibernateUtil {
/** The Constant logger. */
private static final Logger logger = Logger.getLogger(HibernateUtil.class);
/** The session factory. */
@Autowired
private SessionFactory sessionFactory;
/**
* Instantiates a new hibernate util.
*/
public HibernateUtil() {
logger.info("Inside constructor of class" + logger.getName());
}
/**
* Persist the given transient instance, first assigning a generated identifier.
* (Or using the current value of the identifier property if the assigned generator is used.)
* This operation cascades to associated instances if the association is mapped with cascade="save-update".
*
* @param <T> the generic type
* @param entity the entity
* @return the serializable
*/
// Record Create Methods
public <T> Serializable create(final T entity) throws HibernateException{
return sessionFactory.getCurrentSession().save(entity);
}
/**
* Read all records for the passed Entity class. Create a Query instance for the passed Class instance and returns the query results as a List.
* If the query contains multiple results per row, the results are returned in an instance of Object[].
*
* @param <T> the generic type
* @param entityClass the entity class
* @return the list
*/
// Record retrieval Methods
@SuppressWarnings("unchecked")
public <T> List<T> readAll(Class<T> entityClass) throws HibernateException{
return sessionFactory.getCurrentSession().createQuery(" FROM " + entityClass.getName()).list();
}
/**
* Read records through hql. Create a Query instance for the given HQL query string and eturn the query results as a List. If the query contains multiple results per row,
* the results are returned in an instance of Object[].
*
* @param <T> the generic type
* @param hqlQuery the hql query
* @return the list
*/
@SuppressWarnings("unchecked")
public <T> List<T> readAllThroughHQL(String hqlQuery) throws HibernateException{
return sessionFactory.getCurrentSession().createQuery(hqlQuery).list();
}
/**
* Read records through sql. Create a SQLQuery instance for the given SQL query string. Return the query results as a List.
* If the query contains multiple results per row, the results are returned in an instance of Object[].
*
* @param <T> the generic type
* @param sqlQuery the sql query
* @return the list
*/
@SuppressWarnings("rawtypes")
public <T> List readAllThroughSQL(String sqlQuery) throws HibernateException {
return sessionFactory.getCurrentSession().createSQLQuery(sqlQuery).list();
}
/**
* Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance.
* (If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.)
*
* @param <T> the generic type
* @param id the id
* @param entityClass the entity class
* @return the t
*/
@SuppressWarnings("unchecked")
public <T> T readById(Serializable id, Class<T> entityClass) throws HibernateException {
return (T) sessionFactory.getCurrentSession().get(entityClass, id);
}
/**
* Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown.
* This operation cascades to associated instances if the association is mapped with cascade="save-update"
*
* @param <T> the generic type
* @param entity the entity
* @return the t
*/
// Record update Methods
public <T> T update(final T entity) throws HibernateException {
sessionFactory.getCurrentSession().update(entity);
return entity;
}
/**
* Either save(Object) or update(Object) the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking).
* This operation cascades to associated instances if the association is mapped with cascade="save-update".
*
* @param entityObject the entity object
*/
public void createOrUpdate(Object entityObject) throws HibernateException {
sessionFactory.getCurrentSession().saveOrUpdate(entityObject);
}
/**
* Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving Session or a transient instance with an identifier associated
* with existing persistent state. This operation cascades to associated instances if the association is mapped with cascade="delete"
*
* @param <T> the generic type
* @param entity the entity
*/
// Record delete Methods
public <T> void delete(final T entity) throws HibernateException {
sessionFactory.getCurrentSession().delete(entity);
}
/**
* First retrieve the entity from database by using the id passed and then Remove it from the database using same retrieved entity object.
*
* @param <T> the generic type
* @param id the id
* @param entityClass the entity class
*/
public <T> void delete(Serializable id, Class<T> entityClass) throws HibernateException{
T entity = readById(id, entityClass);
delete(entity);
}
}