This is a repost of a post from yesterday. But I've enclosed the code in tags to make it more readable. Sorry for the annoyance.
I'm using Spring 2, Hibernate 3, and JPA annotations. When I write out a parent class where there is a parent child relationship defined in the database and by the annotations, the cascade does not happen. i.e. When I write the parent, it's children are not written.
Here's the springs beans I'm using:
Here's my Parent class:Code:<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName"><value>com.mysql.jdbc.Drive r</value></property> <property name="url"><value>jdbc:mysql://${mysql.host}:${mysql.port}/dandelion</value></property> <!-- <property name="url"><value>jdbc:mysql://${mysql.host}:${mysql.port}/dandelion</value></property> --> <property name="username"><value>${mysql.user}</value></property> <property name="password"><value>${mysql.password}</value></property> </bean> <!-- Hibernate SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotati on.AnnotationSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource"/> </property> <property name="annotatedClasses"> <list> <value>com.adobe.dandelion.dao.model.Parent</value> <value>com.adobe.dandelion.dao.model.Child</value> </list> </property> <property name="annotatedPackages"> <list> <value>com.adobe.dandelion.dao.model</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQ LDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.search.autoregister_listeners">fals e</prop> </props> </property> </bean> <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="childDao" class="com.adobe.dandelion.dao.ChildDaoHibernate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="parentDao" class="com.adobe.dandelion.dao.ParentDaoHibernate" > <property name="sessionFactory" ref="sessionFactory"/> </bean>
Here's the Child class:Code:package com.adobe.dandelion.dao.model; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="parents") public class Parent { private Integer id; private Set<Child> childs = new HashSet(); @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, mappedBy = "parent", fetch = FetchType.LAZY) public Set<Child> getChilds() { return childs; } public void setChilds(Set<Child> childs) { this.childs = childs; } public void addChild(Child child) { if (child == null) throw new IllegalArgumentException("Null child"); if (child.getParent() != null) child.getParent().getChilds().remove(child); child.setParent(this); childs.add(child); } public void removeChild(Child child) { if (child == null) throw new IllegalArgumentException("Null child"); childs.remove(child); child.setParent(null); } }
The Dao for each extend HibernateDaoSupport and each have a method for saving and updating that looks like this:Code:package com.adobe.dandelion.dao.model; 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.Table; @Entity @Table(name = "childs") public class Child { private Integer id = null; private Parent parent = null; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @ManyToOne @JoinColumn(name = "parent", nullable = false) public Parent getParent() { return parent; } public void setParent(Parent parent) { this.parent = parent; } }
The code that creates a Parent and Child and saves the parent looks like this:Code:public void saveOrUpdate( T entity ) { getHibernateTemplate().saveOrUpdate(entity); }
If my understanding is correct, since I marked the classes with annotations specifying cascading inserts and updates, the child should have been written. When I look in the database it is not there.Code:Parent parent = new Parent(); Child child = new Child(); parent.addChild(child); parentDao.saveOrUpdate(parent);
One thing that I wonder about is whether the JPA annotations can be used with hibernate sessions, or do you have to use the JPA entity manager? I also don't understand which Spring is using under the covers in my case.
Any ideas?


Reply With Quote