-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: possible bug in cascading with annotations?
PostPosted: Tue Nov 29, 2005 8:29 am 
Newbie

Joined: Sat Nov 19, 2005 10:10 pm
Posts: 9
I use annotations with hibernate-3.1 rc3. I have discover, that using CascadeType.ALL is not equivalent to {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH}.

Here are my entity classes Report and Auftritt with Many-To-One relation:

Code:
package ftek.model;

import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity(access = AccessType.FIELD)
@Table(schema = "report_apps", name = "REPORTS")
public class Report extends ftek.shared.HibernatePersistent<Long>  {
     @Id
     @Column(name = "REP_ID")
     private Long id;

//   @ManyToOne(cascade = {CascadeType.ALL}, fetch=FetchType.EAGER)
     @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH}, fetch=FetchType.EAGER)
     @JoinColumn(name="REP_AFT_ID", nullable = false, updatable = true)
   private Auftritt auftritt;

     @Column(name = "BEZEICHNUNG")
   private java.lang.String bezeichnung;
   
   public Report() {
      super();
   }

   public Report(java.lang.Long id) {
      super(id);
   }
   
   public Auftritt getAuftritt() {
      return this.auftritt;
   }

   public void setAuftritt(Auftritt auftritt) {
      this.auftritt = auftritt;
   }

   public java.lang.String getBezeichnung() {
      return this.bezeichnung;
   }

   public void setBezeichnung(java.lang.String bezeichnung) {
      this.bezeichnung = bezeichnung;
   }

   public Long getId() {
      return id;
   }

   protected void setId(Long id) {
      this.id = id;
   }   
}


Code:
package ftek.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity(access = AccessType.FIELD)
@SequenceGenerator(name = "SEQ_AFT", sequenceName = "FLEXUP.flx_user_sec")
@Table(schema = "report_apps", name = "AUFTRITTE_BASE")
public class Auftritt extends ftek.shared.HibernatePersistent<Long> {
   @Id(generate = GeneratorType.SEQUENCE, generator = "SEQ_AFT")
   @Column(name = "AFT_ID")
   private Long id;

   @Column(name = "AUFTRITT")
   private java.lang.String text;

   @OneToMany(cascade = { CascadeType.PERSIST }, mappedBy = "auftritt")
   protected Set<Report> reports = new HashSet<Report>();

   @Column(name = "AFT_SPB_ID")
   private Long spbId = new Long(1);

   public Auftritt() {
      super();
   }

   public Auftritt(java.lang.Long id) {
      super();
      this.setId(id);
   }

   public java.lang.String getText() {
      return this.text;
   }

   public void setText(java.lang.String text) {
      this.text = text;
   }

   public Set<Report> getReports() {
      return reports;
   }

   public void setReports(Set<Report> reports) {
      this.reports = reports;
   }

   public Long getId() {
      return id;
   }

   public void setId(Long id) {
      this.id = id;
   }

}


And my code, that uses these classes:
Code:
Auftritt aft = new Auftritt();
aft.setText("test");
      
Report report = new Report(-1L);
report.setBezeichnung("test");
      
report.setAuftritt(aft);
aft.getReports().add(report);
      
report.persist();


I expect, that aft will be persisted using cascading, when I persist report. It works fine, if
@ManyToOne(cascade = {CascadeType.ALL})
syntax is used, and fails in case of
@ManyToOne(cascade = {CascadeType.PERSIST})
with following exception:

Quote:
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: ftek.model.Report.auftritt
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:114)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:501)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:491)
at ftek.shared.HibernatePersistent.persist(HibernatePersistent.java:48)
at ftek.TestMain.main(TestMain.java:24)


I also have tried to use full list of possible values of CascadeType
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH} )
with same result.

Looks like a bug?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 9:22 am 
Newbie

Joined: Sat Nov 19, 2005 10:10 pm
Posts: 9
I forgot to post, that used in test code method persist() implemented in super class as
Code:
public PkType persist() throws SQLException {
        HibernateSession.currentSession().saveOrUpdate(this);
        return this.getId();
}


where HibernateSession is my version of HibernateUtils class.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 9:40 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
the operation cascaded at flush time is SAveOrUpdate for Hibernate3 and Persist for HEM

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 10:49 am 
Newbie

Joined: Sat Nov 19, 2005 10:10 pm
Posts: 9
emmanuel wrote:
the operation cascaded at flush time is SAveOrUpdate for Hibernate3 and Persist for HEM


Yes, I understand it. I use Hibernate3 and call saveOrUpdate. I also call flush explicitly in test code later. The problem is, that cascading is executed only by CascadeType.ALL and is not executed in case of {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH}.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 10:54 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Because ALL includes SAVE_UPDATE, which you don't have.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 11:12 am 
Newbie

Joined: Sat Nov 19, 2005 10:10 pm
Posts: 9
christian wrote:
Because ALL includes SAVE_UPDATE, which you don't have.


There is no SAVE_UPDATE in enum CascadeType!
I also check last version of CascadeType in cvs here:
http://cvs.sourceforge.net/viewcvs.py/hibernate/HibernateExt/ejb-api/src/javax/persistence/CascadeType.java?rev=1.2&view=markup


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 11:18 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
http://cvs.sourceforge.net/viewcvs.py/h ... iew=markup


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 11:43 am 
Newbie

Joined: Sat Nov 19, 2005 10:10 pm
Posts: 9
Oops! I have created my model in time of experiments with HEM. Now I try it with Hibernate3. I can't imagine, that another implementation of CascadeType must be used here. Thank you for help!

Is it means, that I can not create my model once and reuse it with both Hibernate3 and HEM?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 29, 2005 12:01 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
It means that you use saveOrUpdate() with the Session and SAVE_UPDATE cascade type. It means that you use persist() with EM and PERSIST. It also means that persist() on Session is a special case that is not cascaded at flush time.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.