eccentricCoder
eccentricCoder

Reputation: 844

How to restrict associated tables from getting considered for join when using hibernate update() on entity having multiple @ManyToOne associations

I have a Record entity that maintains a @ManyToOne relation with Product_Category table and Price_Category table. The record entity also maintains a @OneToMany association with another table called PendingRecords.

Currently this is working perfectly for hibernate save/persist, in which all the associated tables also get modified when specific conditions are met. The problem is these associated entities are also getting considered on hibernate update/delete which is not what I intended to do. I want to restrict these entites from getting considered and allow change only on insert.

Following are the entity class mappings

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)

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

Following are the associated 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)

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

and finally,

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)

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

The entity associations are working fine when I perform the insert (hibernate persist/save). The problem is when I try to update the Record, hibernate is trying to update all the associated entries also like

   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=?

What should be done to prevent considering these entities for join operations while updating Record entity? Because this is an additional overhead and also generates ClassCastException. I need associated entites to be changed only during persit or save and not during update or delete.

I am getting the following error during update

Servlet.service() for servlet dispatcher threw exception: java.lang.ClassCastException: com.myapps.models.PriceCategory cannot be cast to java.io.Serializable

Should I specify CascadeType? Or should i use hibernate CascadeType instead of JPA's which I am currently using for PendingRecords? Or is there another way? Please help me resolve this.

Thanks in advance.

Upvotes: 1

Views: 612

Answers (1)

crizzis
crizzis

Reputation: 10716

I need associated entites to be changed only during persit or save and not during update or delete

If, once the related entities are set at persist time, they should never be overwritten with another entity instance, use @JoinColumn(updatable=false).

Note that because of Hibernate's flush operation order, it the related entities do not already exist, you might need to save them first, flush the EntityManager, and only then save the top-level entity.

What should be done to prevent considering these entities for join operations while updating Record entity?

Try @ManyToOne(fetch=LAZY). I am not entirely sure this will work during a merge, though, as there are many reasons for Hibernate to fetch related entities during a merge. If it doesn't work, you might need to write a custom update query.

Upvotes: 1

Related Questions