基本上,我该如何制作它以便我可以在创建人之后将新的TestEntity添加到测试集中?另外,如何添加具有TestEntity集合的人?我是Hibernate的新手,所以我觉得我必须遗漏一些东西,因为这看起来像是一个非常常见的用例。
我尝试过的一些事情:
尝试#1:
PersonEntity person = createPerson("username");
TestEntity test = new TestEntity();
test.setTestId("2342");
test.setTestName("test name");
personDao.add(person);
person.addTest(test);
这会导致人员被保存但没有测试信息。切换add和addTest不会改变任何东西。
尝试#2:
将这样的方法添加到我的Dao中(基于http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-parentchild.html):
public void addTest(String personId, TestEntity test)
{
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();
}
}
并且这样打电话:
personDao.add(person);
personDao.addTest("username", test);
但是,我收到此错误:org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
尝试#3:
在我的dao和实体类中添加了@Transaction注释,并将以下配置添加到我的应用程序上下文中:
<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 />
现在,使用我在尝试#2中创建并以相同方式调用它的方法,我得到stackoverflow错误。
编辑更新:但是,如果我从PersonEntity中的hashCode方法中删除测试集,它可以正常工作。我也可以使用person.addTest(test),它将在持久化person实体之前处理向person实体添加集合。但是,这似乎不是最好的方法,不是吗?什么是使这项工作的最佳方式?我添加的dao方法似乎会拨打超过必要的电话?
我的课程:
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());
}
}
答案 0 :(得分:0)
我认为您必须将方法名称更改为setTest(...),因为hibernate在尝试对属性执行操作时遵循java bean约定。 改变这一点,我希望它应该工作正常。 其余代码看起来很好。