How to add/delete elements from a collection on an entity in Hibernate?
Basically, how would I make it so that I can add a new TestEntity to the test set after the person has already been created? Also, how can I add a person that has a collection of TestEntity? I'm new to Hibernate so I feel I must be missing something since this would seem like a very common use case.
Some things I've tried:
Attempt #1:
PersonEntity person = createPerson("username");
TestEntity test = new TestEntity();
test.setTestId("2342");
test.setTestName("test name");
personDao.add(person);
person.addTest(test);
This results in the person being saved but no test information. Switching add and addTest does not change anything.
Attempt #2:
Adding a method like this to my Dao (based on http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html):
public void addTest(String personId, TestEntity test)
{开发者_C百科
PersonEntity entity = (PersonEntity) getHibernateTemplate().getSessionFactory().getCurrentSession().load(PersonEntity.class, personId);
if (entity != null)
{
test.setPerson(entity);
entity.getTest().add(test);
getHibernateTemplate().getSessionFactory().getCurrentSession().save(entity);
getHibernateTemplate().getSessionFactory().getCurrentSession().flush();
}
}
And calling like this:
personDao.add(person);
personDao.addTest("username", test);
However, I get this error: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Attempt #3:
Added @Transaction annotation to my dao and entity classes and added the following config to my app context:
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- org.springframework.transaction.jta.JtaTransactionManager org.springframework.jdbc.datasource.DataSourceTransactionManager -->
<property name="dataSource" ref="dataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
Now, using that method I created in attempt #2 and calling it in the same way, I get a stackoverflow error.
Edit Update: However, if I remove the test set from my hashCode method in PersonEntity, it works. I can also use person.addTest(test) and that will take care of adding a collection to the person entity before persisting the person entity. However, this really doesn't seem like it would be the best way to do it, no? What would be the best way to make this work? That dao method I added seems like it would be making more calls than necessary?
My classes:
PERSON
@Entity
@Table(name = "PERSON")
public class PersonEntity implements Serializable
{
private static final long serialVersionUID = -1699435979266209440L;
@Id
@Column(name = "PERSON_ID", length = 25, nullable = false)
private String personId;
@LazyCollection(value = LazyCollectionOption.FALSE)
@Cascade(CascadeType.ALL)
@OneToMany(targetEntity = TestEntity.class, mappedBy = "person")
@Where(clause="1=1")
private Set<TestEntity> test;
public void addTest(TestEntity testEntity)
{
testEntity.setPerson(this);
test.add(testEntity);
}
}
TEST
@Entity
@Table(name = "TEST")
public class TestEntity implements Serializable
{
private static final long serialVersionUID = -6524488155196023818L;
@Id
@Column(name = "TEST_ID", length = 36, nullable = false)
private String testId;
@ManyToOne
@Cascade(CascadeType.ALL)
@Index(name = "TEST_PERSON_ID_INDEX")
@JoinColumn(name = "PERSON_ID")
@ForeignKey(name = "FKT1_PERSON_ID")
private PersonEntity person;
@Column(name = "TEST_NAME", length = 60, nullable = false)
private String testName;
}
PersonDaoHibernate
public class PersonDaoHibernate extends HibernateDaoSupport implements PersonDao
{
public String add(PersonEntity person)
{
getHibernateTemplate().merge(person);
return person.getPersonId();
}
public void delete(String id)
{
Object entity = getHibernateTemplate().get(PersonEntity.class, id);
if (entity != null)
{
getHibernateTemplate().delete(entity);
}
}
public PersonEntity getById(String id)
{
return getHibernateTemplate().get(PersonEntity.class, id.toUpperCase());
}
}
I think you will have to change the method name to setTest(...), since hibernate follows java bean convention while trying to do the operation on properties. Change that and I hope it should work fine. Rest of code looks fine.
精彩评论