Java 在对具有多个@manytone关联的实体使用hibernate update()时,如何限制关联表被考虑加入
我有一个记录实体,它与Product\u Category表和Price\u Category表保持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更新/删除时也会考虑这些关联实体,这不是我想要做的。我想限制这些实体不被考虑,只允许在插入时进行更改 以
@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
设置为不同的实体实例(以查看是否需要更新相应的联接列)谢谢。我会试试看。