Java 在对具有多个@manytone关联的实体使用hibernate update()时,如何限制关联表被考虑加入

Java 在对具有多个@manytone关联的实体使用hibernate update()时,如何限制关联表被考虑加入,java,hibernate,jpa,hibernate-mapping,Java,Hibernate,Jpa,Hibernate Mapping,我有一个记录实体,它与Product\u Category表和Price\u Category表保持@ManyToOne关系。记录实体还与另一个名为PendingRecords的表保持@OneToMany关联 目前,这对于hibernate save/persist非常有效,在hibernate save/persist中,当满足特定条件时,所有关联的表都会被修改。问题是,在hibernate更新/删除时也会考虑这些关联实体,这不是我想要做的。我想限制这些实体不被考虑,只允许在插入时进行更改 以

我有一个记录实体,它与Product\u Category表和Price\u Category表保持
@ManyToOne
关系。记录实体还与另一个名为PendingRecords的表保持
@OneToMany
关联

目前,这对于hibernate save/persist非常有效,在hibernate save/persist中,当满足特定条件时,所有关联的表都会被修改。问题是,在hibernate更新/删除时也会考虑这些关联实体,这不是我想要做的。我想限制这些实体不被考虑,只允许在插入时进行更改

以下是实体类映射

Record.java

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.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "ITEM_RECORDS")
public class Record {

-------------------------


@ManyToOne(optional=false)
@JoinColumn(name = "PRICE_CATEGORY", referencedColumnName="price_category", nullable=false)
private PriceCategory price_category;

@ManyToOne(optional=false)
@JoinColumn(name = "PRODUCT_CATEGORY", referencedColumnName="product_category", nullable=false)
private ProductCategory product_category;

@OneToOne(mappedBy="record", cascade = CascadeType.ALL)
private PendingRecords pendingRecord;

----------------------

(getter setter methods)

-----------------------
@Entity
@Table(name = "PRICE_CATEGORY")
public class PriceCategory{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "PRICE_CATEGORY")
private String price_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PRODUCT_CATEGORY")
public class ProductCategory {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

@Column(name = "PRODUCT_CATEGORY")
private String product_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PENDING_RECORDS")
public class PendingRecords{


@Id
@Column(name = "PENDING_RECORD_NO")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="record"))
private Long pending_record_id;

----------------------

@OneToOne
@PrimaryKeyJoinColumn
private Record record;

-------------------------

(getters-setters)

-------------------------
以下是相关表格

PriceCategory.java

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.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "ITEM_RECORDS")
public class Record {

-------------------------


@ManyToOne(optional=false)
@JoinColumn(name = "PRICE_CATEGORY", referencedColumnName="price_category", nullable=false)
private PriceCategory price_category;

@ManyToOne(optional=false)
@JoinColumn(name = "PRODUCT_CATEGORY", referencedColumnName="product_category", nullable=false)
private ProductCategory product_category;

@OneToOne(mappedBy="record", cascade = CascadeType.ALL)
private PendingRecords pendingRecord;

----------------------

(getter setter methods)

-----------------------
@Entity
@Table(name = "PRICE_CATEGORY")
public class PriceCategory{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "PRICE_CATEGORY")
private String price_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PRODUCT_CATEGORY")
public class ProductCategory {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

@Column(name = "PRODUCT_CATEGORY")
private String product_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PENDING_RECORDS")
public class PendingRecords{


@Id
@Column(name = "PENDING_RECORD_NO")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="record"))
private Long pending_record_id;

----------------------

@OneToOne
@PrimaryKeyJoinColumn
private Record record;

-------------------------

(getters-setters)

-------------------------
ProductCategory.java

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.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "ITEM_RECORDS")
public class Record {

-------------------------


@ManyToOne(optional=false)
@JoinColumn(name = "PRICE_CATEGORY", referencedColumnName="price_category", nullable=false)
private PriceCategory price_category;

@ManyToOne(optional=false)
@JoinColumn(name = "PRODUCT_CATEGORY", referencedColumnName="product_category", nullable=false)
private ProductCategory product_category;

@OneToOne(mappedBy="record", cascade = CascadeType.ALL)
private PendingRecords pendingRecord;

----------------------

(getter setter methods)

-----------------------
@Entity
@Table(name = "PRICE_CATEGORY")
public class PriceCategory{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "PRICE_CATEGORY")
private String price_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PRODUCT_CATEGORY")
public class ProductCategory {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

@Column(name = "PRODUCT_CATEGORY")
private String product_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PENDING_RECORDS")
public class PendingRecords{


@Id
@Column(name = "PENDING_RECORD_NO")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="record"))
private Long pending_record_id;

----------------------

@OneToOne
@PrimaryKeyJoinColumn
private Record record;

-------------------------

(getters-setters)

-------------------------
最后

PendingRecords.java

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.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "ITEM_RECORDS")
public class Record {

-------------------------


@ManyToOne(optional=false)
@JoinColumn(name = "PRICE_CATEGORY", referencedColumnName="price_category", nullable=false)
private PriceCategory price_category;

@ManyToOne(optional=false)
@JoinColumn(name = "PRODUCT_CATEGORY", referencedColumnName="product_category", nullable=false)
private ProductCategory product_category;

@OneToOne(mappedBy="record", cascade = CascadeType.ALL)
private PendingRecords pendingRecord;

----------------------

(getter setter methods)

-----------------------
@Entity
@Table(name = "PRICE_CATEGORY")
public class PriceCategory{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "PRICE_CATEGORY")
private String price_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PRODUCT_CATEGORY")
public class ProductCategory {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

@Column(name = "PRODUCT_CATEGORY")
private String product_category;

@Column(name = "DESCRIPTION")
private String description;

----------------------------

 (getter-setters)

----------------------------
@Entity
@Table(name = "PENDING_RECORDS")
public class PendingRecords{


@Id
@Column(name = "PENDING_RECORD_NO")
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign",parameters=@Parameter(name="property", value="record"))
private Long pending_record_id;

----------------------

@OneToOne
@PrimaryKeyJoinColumn
private Record record;

-------------------------

(getters-setters)

-------------------------
当我执行插入(hibernate persist/save)时,实体关联工作正常。问题是当我试图更新记录时,hibernate试图更新所有相关的条目,如

   select
   this_.RECORD_NO as REC_REC1_1_3_,

   this_.PRICE_CATEGORY as PRICE_CA10_1_3_,

   this_.PRODUCT_CATEGORY as PRODUCT11_1_3_,

   pricecatego2_.id as id1_0_0_,
   pricecatego2_.PRICE_CATEGORY as PRICE_CAT2_0_0_,
   pricecatego2_.DESCRIPTION as DESCRIPT3_0_0_,
   productcat3_.ID as ID1_3_1_,
   productcat3_.DESCRIPTION as DESCRIPT2_3_1_,
   productcat3_.PRODUCT_CATEGORY as PRODUCT_3_3_1_,
   pendingrec4_.PENDING_RECORD_NO as REC_REC1_2_2_,
   ---------------------------
  from
      ITEM_RECORDS this_ 
  inner join
      PRICE_CATEGORY pricecatego2_ 
          on this_.PRICE_CATEGORY=pricecatego2_.PRICE_CATEGORY 
  inner join
      PRODUCT_CATEGORY productcat3_ 
          on this_.PRODUCT_CATEGORY=productcat3_.PRODUCT_CATEGORY 
  left outer join
      PENDING_RECORDS pendingrec4_ 
          on this_.PENDING_RECORD_NO=pendingrec4_.PENDING_RECORD_NO 
  where
      this_.PENDING_RECORD_NO=?
在更新记录实体时,应采取哪些措施防止将这些实体视为联接操作?因为这是一个额外的开销,并且还会生成
ClassCastException
。我需要关联的实体仅在persit或save期间更改,而不是在更新或删除期间更改

我在更新过程中遇到以下错误

Servlet.service() for servlet dispatcher threw exception: java.lang.ClassCastException: com.myapps.models.PriceCategory cannot be cast to java.io.Serializable
我应该指定级联类型吗?或者我应该使用hibernate CascadeType而不是我目前用于PendingRecords的JPA吗?还是有别的办法?请帮我解决这个问题

提前谢谢

我只需要在perit或save期间更改关联的实体 而不是在更新或删除期间

如果在持久化时间设置相关实体后,不应使用其他实体实例覆盖它们,请使用
@JoinColumn(updateable=false)

请注意,由于Hibernate的刷新操作顺序,如果相关实体不存在,则可能需要先保存它们,刷新
EntityManager
,然后才保存顶级实体

应采取哪些措施防止考虑加入这些实体 更新记录实体时的操作


试试
@ManyToOne(fetch=LAZY)
。不过,我不完全确定这在合并期间是否有效,因为Hibernate在合并期间获取相关实体有很多原因。如果不起作用,您可能需要编写一个自定义更新查询

删除CascadeType对您有用吗?@daveParal如果我错了,请原谅,但是不是
CascadeType。当您需要从两个实体中删除条目时,请使用“删除”
?在这里,它已经开始工作了。问题是在更新过程中,所有实体都在更新,这不是我想要的。我希望仅对调用update()的实体进行更新。同样,如上面的代码所示,只有一个关联实体正在使用级联选项,而其他两个实体没有。但是当我调用更新时,hibernate正在尝试更新所有4个实体。错误表明您没有实现可序列化的
接口。@daveParal谢谢,我注意到了,但只有在更新过程中考虑这些实体的联接操作时,才会出现此问题。我不希望在更新期间发生这种情况。那么,如果异常阻止事务提交,您如何知道实体正在更新?您是否看到
UPDATE
查询被发送到数据库?Hibernate(可能)没有尝试更新属于
PriceCategory
ProductCategory
的数据。只需检查是否已将
Record.price\u category
Record.product\u category
设置为不同的实体实例(以查看是否需要更新相应的联接列)谢谢。我会试试看。