Как добавить / удалить элементы из коллекции на объекте в Hibernate? - PullRequest
2 голосов
/ 01 мая 2011

Как мне сделать так, чтобы я мог добавить новый 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:

Добавил аннотацию @Transaction в мои классы dao и entity и добавил следующую конфигурацию в контекст моего приложения:

<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, и вызывая его таким же образом, я получаюошибка переполнения стека.

Редактировать обновление: Однако, если я удаляю набор тестов из моего метода hashCode в PersonEntity, он работает. Я также могу использовать person.addTest (test), и это позаботится о добавлении коллекциидля сущности person перед сохранением сущности 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);
    }

    }

ТЕСТ

@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());
    }

}

1 Ответ

0 голосов
/ 01 мая 2011

Я думаю, вам придется изменить имя метода на setTest (...), так как hibernate следует соглашению с Java-бином при попытке выполнить операцию над свойствами. Измените это, и я надеюсь, что это должно работать хорошо. Остальная часть кода выглядит нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...