Сохранение объекта в базе данных с помощью JPA и автоматически сгенерированного идентификатора первичного ключа

У меня есть полное веб-приложение Java EE со слоем представления и базой данных. Я использую derby с Glassfish 3.1 и JPA для сохранения постоянства. Я создал Read ok, но теперь у меня возникают проблемы с созданием и сохранением в базе данных. Я думаю, что я близок, но что-то не так с тем, как я пытаюсь создать.

Вот мой код EAO:

/**

 * Session Bean implementation class XRSSeao

 */

@Stateless

@LocalBean

public class XRSSeao {



@PersistenceContext

EntityManager em;

public XRSSeao() {}




    public void addEvent(String update){

    Feed feed = new Feed();

    feed.setStatus(update);

    feed.setId(2);

        em.getTransaction().begin();

            em.persist(feed);

            em.flush();

            em.clear();

        em.getTransaction().commit();

}

}

Это будет вызвано из другого EJB. Я также не хочу устанавливать идентификатор, так как это первичный ключ, который я хочу генерировать всякий раз, когда я вызываю метод persist. Ошибка, которую я получаю при тестировании:

«Вызвано: java.lang.IllegalStateException: Описание исключения: невозможно использовать EntityTransaction при использовании JTA».

Если вы не знаете, в чем проблема с этим кодом, но можете привести пример простого сохранения с автоматически сгенерированным первичным ключом, это будет так же полезно.

Это мой метод чтения, который работает:

public String lastUpdate(){
    String resultString;
    Query q = em.createQuery("SELECT x FROM Feed x WHERE x.id = 1");
    List<Feed> ListofStatus =  q.getResultList();  //alternatively you can use getResultList() for non 1 object is expected. 
    Feed returnStatusObject = ListofStatus.get(0);
    resultString = returnStatusObject.getStatus();
    return resultString;

}

Если мне не нужно использовать Transaction(), я не нашел в Интернете примера, который не использует его для создания.


person Randnum    schedule 14.11.2011    source источник


Ответы (1)


Вы используете EJB/JTA с transaction-type="JTA". Затем контейнер сам будет управлять транзакциями. Вы можете управлять транзакциями с помощью @TransactionAttribute и @TransactionAttributeType аннотаций класса/методов EJB (которые по умолчанию, однако, должны быть не нужно). Учебники, которые вы читали, по-видимому, не использовали EJB/JTA, а только транзакции, управляемые приложением с transaction-type="RESOURCE_LOCAL". Вам следует прочитать учебные пособия по JPA, предназначенные для использования с EJB/JTA.

Чтобы решить вашу проблему - я предполагаю, что вы хотите продолжать использовать EJB/JTA-, замените

em.getTransaction().begin();
em.persist(feed);
em.flush();
em.clear();
em.getTransaction().commit();

by

em.persist(feed);

Смотрите также:

person BalusC    schedule 14.11.2011
comment
Что вы имеете в виду, что контейнер будет управлять транзакцией? Означает ли это, что мне не нужно на самом деле совершать вызовы самой транзакции, я могу просто создать новую сущность, и поскольку она была аннотирована как @Entity, менеджер будет знать, как управлять транзакцией? - person Randnum; 14.11.2011
comment
Да, вам не нужно управлять ими самостоятельно. Нет, это потому, что вы используете @Stateless EJB с transaction-type="JTA". - person BalusC; 14.11.2011
comment
если класс Feed является моим объектом @Entity, как будет выглядеть такой вызов? Фид фид = новый фид(); ? Будет ли это все, что мне нужно? - person Randnum; 14.11.2011
comment
Я понятия не имею, о чем вы спрашиваете, но эта строка кода просто создает неуправляемый объект. Только когда вы persist(), он будет сохранен в БД, и будет установлен его новый идентификатор (если у вас есть правильные аннотации @Id и @GeneratedValue). Обычно вам не нужно вручную устанавливать идентификатор. - person BalusC; 14.11.2011
comment
Отлично, это только что сработало. На случай, если это прочтут другие. Я только что создал новый объект и назвал его em.persist(entity); BalusC как всегда полезен. - person Randnum; 15.11.2011