在具有多个@ManyToOne 关联的实体上使用 hibernate update() 时如何限制关联表被考虑加入
How to restrict associated tables from getting considered for join when using hibernate update() on entity having multiple @ManyToOne associations
我有一个 Record 实体,它与 Product_Category table 和 Price_Category table 保持 @ManyToOne
关系。记录实体还与另一个名为 PendingRecords 的 table 保持 @OneToMany
关联。
目前这对休眠 save/persist 非常有效,其中所有关联的 table 也会在满足特定条件时进行修改。问题是这些关联的实体也在休眠 update/delete 上得到考虑,这不是我打算做的。我想限制这些实体被考虑并只允许在插入时进行更改。
以下是实体 class 映射
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)
-----------------------
以下是关联的 tables
PriceCategory.java
@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)
----------------------------
ProductCategory.java
@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)
----------------------------
最后,
PendingRecords.java
@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)
-------------------------
当我执行插入时,实体关联工作正常(休眠 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=?
应该怎样做才能避免在更新 Record 实体时考虑将这些实体用于连接操作?因为这是额外的开销并且还会生成 ClassCastException
。我只需要在保存或保存期间更改关联的实体,而不是在更新或删除期间更改。
我在更新期间遇到以下错误
Servlet.service() for servlet dispatcher threw exception: java.lang.ClassCastException: com.myapps.models.PriceCategory cannot be cast to java.io.Serializable
我应该指定 CascadeType 吗?或者我应该使用 hibernate CascadeType 而不是我目前用于 PendingRecords 的 JPA?或者还有其他方法吗?请帮我解决这个问题。
提前致谢。
I need associated entites to be changed only during persit or save
and not during update or delete
如果在持久化时设置了相关实体,则它们永远不应被另一个实体实例覆盖,请使用 @JoinColumn(updatable=false)
。
请注意,由于 Hibernate 的刷新操作顺序,相关实体尚不存在,您可能需要先保存它们,刷新 EntityManager
,然后才保存顶级实体。
What should be done to prevent considering these entities for join
operations while updating Record entity?
尝试@ManyToOne(fetch=LAZY)
。不过,我不完全确定这在合并期间是否有效,因为 Hibernate 在合并期间获取相关实体的原因有很多。如果它不起作用,您可能需要编写自定义更新查询。
我有一个 Record 实体,它与 Product_Category table 和 Price_Category table 保持 @ManyToOne
关系。记录实体还与另一个名为 PendingRecords 的 table 保持 @OneToMany
关联。
目前这对休眠 save/persist 非常有效,其中所有关联的 table 也会在满足特定条件时进行修改。问题是这些关联的实体也在休眠 update/delete 上得到考虑,这不是我打算做的。我想限制这些实体被考虑并只允许在插入时进行更改。
以下是实体 class 映射
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)
-----------------------
以下是关联的 tables
PriceCategory.java
@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)
----------------------------
ProductCategory.java
@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)
----------------------------
最后,
PendingRecords.java
@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)
-------------------------
当我执行插入时,实体关联工作正常(休眠 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=?
应该怎样做才能避免在更新 Record 实体时考虑将这些实体用于连接操作?因为这是额外的开销并且还会生成 ClassCastException
。我只需要在保存或保存期间更改关联的实体,而不是在更新或删除期间更改。
我在更新期间遇到以下错误
Servlet.service() for servlet dispatcher threw exception: java.lang.ClassCastException: com.myapps.models.PriceCategory cannot be cast to java.io.Serializable
我应该指定 CascadeType 吗?或者我应该使用 hibernate CascadeType 而不是我目前用于 PendingRecords 的 JPA?或者还有其他方法吗?请帮我解决这个问题。
提前致谢。
I need associated entites to be changed only during persit or save and not during update or delete
如果在持久化时设置了相关实体,则它们永远不应被另一个实体实例覆盖,请使用 @JoinColumn(updatable=false)
。
请注意,由于 Hibernate 的刷新操作顺序,相关实体尚不存在,您可能需要先保存它们,刷新 EntityManager
,然后才保存顶级实体。
What should be done to prevent considering these entities for join operations while updating Record entity?
尝试@ManyToOne(fetch=LAZY)
。不过,我不完全确定这在合并期间是否有效,因为 Hibernate 在合并期间获取相关实体的原因有很多。如果它不起作用,您可能需要编写自定义更新查询。