Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ошибка Cannot persist detached object 
V
    Опции темы
aol
Дата 23.10.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



используется jsf
для примера есть 2 класса, user и car, то есть один юзер имеет много машин, ну и каждая машина имеет еще много фсего в отдельной таблице, для этого сделал у нее свой id и id юзера

Код

@Entity
@Table(name = "user")
public class User implements Serializable {

@Id
@Column(name = "user_id", updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getUserId()       {return userId;}
...




Код

@Entity
@Table(name = "car")
public class Car implements Serializable {
private User user;
private Long userId;
private Long carId;
....
@Id
@Column(name = "car_id")
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getCarId() { return carId; }

@Column(name = "user_id", updatable = false, insertable = false)
public Long getUserId() { return userId; }

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
public User getUser()   { return user; }

public void setUser(User user)      { this.user = user; this.userId = user.getUserId(); }
....


нужно добавить новую машину к юзеру
вытаскиваю юзера из сессии и  
 
Код

     car.setUser(u);
...
      em.getTransaction().begin();
      em.persist(car);
      em.getTransaction().commit();

...
один раз вроде добавляется ок, но потом Cannot persist detached object User, бывает и тоже самое для Car
как понимаю нужно перед каждым persist делать сначала find для этого обьекта. но и он тоже выдает такую же ошибку,
как правильно работать с этими персистанс обьектами ?

спасибо


  

Это сообщение отредактировал(а) aol - 23.10.2008, 21:49
PM MAIL   Вверх
v2v
Дата 23.10.2008, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1620
Регистрация: 20.9.2006
Где: Киев

Репутация: 9
Всего: 56



Я вобще - то этой спецификацией не пользуюсь, но кажется: persist используется при создании, дальше работает merge .


--------------------
PM   Вверх
aol
Дата 23.10.2008, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



merge вроде для update можно использовать, не уверен
но он тоже не работает
на форуме забугорном читал что persist да и по спецификации jpa, обьекты должны быть new, то есть новые перед каждым persist и тд.. но как их вытащить если em.find(Car.class, id) например тоже выдает ошибку такую.

PM MAIL   Вверх
powerOn
Дата 24.10.2008, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  24.10.2008,  00:55 Найти цитируемый пост)
em.find(Car.class, id) например тоже выдает ошибку такую.


Не может find такую же ошибку выдавать. Максимум IllegalArgumentException может выдать. 
Метод merge так же как и метод persist сохраняет новый объект, если он действительно новый. Из спецификации:
Цитата

• If X is a new entity instance, a new managed entity instance X' is created and the state of X is
copied into the new managed entity instance X'.


Приведите ваш код полностью.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 24.10.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



прикрепил атачем, много там кода для страницы мне показалось.
класс Contract связан через форегн кей c User, работает отлично, при попытке сделать у контракта свой id и добавить поле с userId опять лезут ошибки
JPABean `инджектиться` через faces-config.xml




Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  model.zip 5,63 Kb
PM MAIL   Вверх
powerOn
Дата 24.10.2008, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Во-первых, если Вы используете EJB 3.0, то почему не инжектируете через @PersistenseContext? Быть может лучше доверить управление транзакциями контейнеру?

Во вторых, заметил у Вас часто используются подобные строки кода:
Код

        EntityManager em = jpaBean.getEMF().createEntityManager();
        Advertiser adv = null;
        try
        {
            em.getTransaction().begin();
            adv = em.find(Advertiser.class, id);
            em.refresh(adv);
            em.getTransaction().commit();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return adv;


Во-вторых, зачем делать refresh после find, да еще и в отдельной транзакции? Потом, каждый раз перед новой операцией (что было также замечено в коде) создавая новый EntityManager, Вы рискуете попасть на  тот самый "detached object exception". Поскольку объект изначально был загружен в другом контексте, а значит связан с ним (с другим контекстом). При попытке вызова persist на detached объекте будет выброшено EntityExistsException. Решать такую проблему можно работая с одним экземпляром EntityManager в пределах всей бизнес-операции, т.е. методы для поиска/добавления/изменения на одном и том же экземпляре EntityManager в пределах одного (а иногда и нескольких) запросов.




 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 00:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



refresh в бине ContractManager в методе findContract для того чтобы после find, обновился обьект contract, так как если в базе например вручную изменить поле в данном случае готовности контракта, то без refresh он не обновляется и на экране видны старые данные.
а то что не на том месте, так это я ошибся,
наверное так надо было
Код

..
      em.getTransaction().begin();
      contract = em.find(Contract.class, userId);
      em.refresh(contract);
      em.getTransaction().commit();
..


про EntityManager не знал что нужен один для всех, поэтому я JPABean закешировал путем помещения в файле faces-config.xml

Код

..
  <managed-bean>
    <managed-bean-name>jpaBean</managed-bean-name>
    <managed-bean-class>portal.db.service.JPABean</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>


и 

Код

  <managed-bean>
    <managed-bean-name>contractManager</managed-bean-name>
    <managed-bean-class>portal.db.ContractManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>jpaBean</property-name>
      <value>#{jpaBean}</value>
    </managed-property>
  </managed-bean>


а потом просто брал в бинах у которых это есть это свойство

Код

EntityManager em = jpaBean.getEMF().createEntityManager();


то есть мне нужно просто перенести в эти бины обьект EntityManager, и как так обьявить ?

Код

@Stateless
public class ContractManager {

@PersistenseContext
EntityManager em;
..

  public boolean addContract(Contract contract){
    boolean ret = false;
    try{
      em.getTransaction().begin();
      em.merge(contract);
      em.getTransaction().commit();
      ret = true;
    } finally {
      em.close();
    }
    return ret;
  }

..






Это сообщение отредактировал(а) powerOn - 25.10.2008, 00:12
PM MAIL   Вверх
powerOn
Дата 25.10.2008, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  01:02 Найти цитируемый пост)
refresh в бине ContractManager в методе findContract для того чтобы после find, обновился обьект contract, так как если в базе например вручную изменить поле в данном случае готовности контракта, то без refresh он не обновляется и на экране видны старые данные.


Это весьма тонкий вопрос, относящийся к параллельно выполняемым задачам. Существует ряд проблем, если планируется что несколько потоков будут одновременно использовать одни данные, например Repetable Read или Phantom Insert. Они разрешается выставлением правильного уровня изоляции для транзакционного ресурса или/и блокировками. Посмотрите вот эту статейку.

Цитата(aol @  25.10.2008,  01:02 Найти цитируемый пост)
то есть мне нужно просто перенести в эти бины обьект EntityManager, и как так обьявить ?


К сожалению, с JSF я достаточно давно работал и успел его подзабыть. Но предполагаю, что JavaEE5 контейнер должен инжектировать EJB компоненты в JSF бины через @EJB аннотацию (вроде в JSF 1.2 это получалось). Если это так, то вам следует пойти таким путем. При этом EntityManager так же будет инжектирован в Ваши EJB. Транзакции открывать и закрывать самостоятельно не нужно, это сделает за Вас контейнер. Посмотрите аннотации @TransactionAttribute.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 01:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



не очень понял про инжектировать EJB компоненты в JSF бины. 
попробую описать как работает схема сейчас.

есть в faces-config.xml следущие записи

WelcomeBean просто класс в котором есть поле типа СontractBean

 
Код

 <managed-bean>
    <managed-bean-name>WelcomePage</managed-bean-name>
    <managed-bean-class>portal.web.bean.rumor.WelcomeBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>contractBean</property-name>
      <value>#{contractBean}</value>
    </managed-property>
  </managed-bean>


в свою очередь ContractBean содержит в себе 2 поля, contractManager как раз для работы с бд и Сontract - а это сам @Entity который и сохраняется

  
Код

<managed-bean>
    <managed-bean-name>contractBean</managed-bean-name>
    <managed-bean-class>portal.web.bean.rumor.ContractBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>contractManager</property-name>
      <value>#{contractManager}</value>
    </managed-property>
    <managed-property>
      <property-name>contract</property-name>
      <value>#{contract}</value>
    </managed-property>
  </managed-bean>


ContractManager имеет поле типа JPABean 

  
Код

<managed-bean>
    <managed-bean-name>contractManager</managed-bean-name>
    <managed-bean-class>portal.db.ContractManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>jpaBean</property-name>
      <value>#{jpaBean}</value>
    </managed-property>
  </managed-bean>


а JPABean имеет жизненый цикл application, то есть живет пока сервак не умрет

  
Код

<managed-bean>
    <managed-bean-name>jpaBean</managed-bean-name>
    <managed-bean-class>portal.db.service.JPABean</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>


а он просто вот что 

Код

public class JPABean {
  protected EntityManagerFactory emf;

  public EntityManagerFactory getEMF(){
    if(emf == null){
      emf = Persistence.createEntityManagerFactory("portalJPA");
    }
    return emf;
  }
}


на jsf есть такие выражения 

Код

<h:inputText value="#{WelcomePage.contractBean.contract.organizationName}" id="companyName"
                     styleClass="inputNoLabel htmlInput" required="true" requiredMessage="*"/>


когда с jsf, вызывается метод например #{WelcomePage.contractBean.createContract}
то бины и их поля которые описаны данным образом в faces-config.xml создаются так называемым путем инжектирования, 

то есть бин ContractManager имеющий у себя поле типа 

private JPABean jpaBean 
и его сеттеры и геттеры 
public JPABean getJpaBean() { return jpaBean; }
public void setJpaBean(JPABean jpaBean) { this.jpaBean = jpaBean; }

после вызова соответсвующей jsp, может обращаться у своему свойству jpaBean, что я и делаю для записи обьекта в бд, получив от jpaBean
EntityManager, EntityManager em = jpaBean.getEMF().createEntityManager();

а раз Вы говорите что EntityManager нужен для всех один, то значит мне просто нужно перенести сам EntityManager 
в бин который общается с бд, ContractManager 

@PersistenseContext
EntityManager em;

то есть эта запись равносильна EntityManager em = jpaBean.getEMF().createEntityManager(); или если напрямую то 
EntityManager em = Persistence.createEntityManagerFactory("portalJPA"); - что описано в persistace.xml ?

прощу прощения что так фсе подробно, просто сам пытаюсь понять как это все должно работать )




Это сообщение отредактировал(а) aol - 25.10.2008, 01:10
PM MAIL   Вверх
powerOn
Дата 25.10.2008, 01:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  02:09 Найти цитируемый пост)
не очень понял про инжектировать EJB компоненты в JSF бины. 


Точно так же как Вы инжектируете EntityManager в EJB компоненты с помощью аннотации @PersistenseContext, Вы можете инжектировать EJB компоненты в BackingBean-ы JSF. Проведите аналогию с инжектированием, которое происходит с JSF бинами, но только не нужно писать xml конфигурацию, контейнер получит всю необходимую информацию из аннотаций.

Еще как вариант, самостоятельно создавать новый EntityManager (как это у Вас и было), но в request scope бине. При придется самостоятельно следить за транзакциями (открывать, закрывать), а во время Unit такой подход будет лишней палкой в колесе.


Цитата(aol @  25.10.2008,  02:09 Найти цитируемый пост)
@PersistenseContext
EntityManager em;

то есть эта запись равносильна EntityManager em = jpaBean.getEMF().createEntityManager(); или если напрямую то 
EntityManager em = Persistence.createEntityManagerFactory("portalJPA"); - что описано в persistace.xml ?


Да, при этом имя персистент юнита можно указать в аннотации @PersistenseContext(unitName="portalJPA").



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



до конца не понимаю тогда в чем будет разница, то что я сейчас создаю EntityManager из обьекта который висит постоянно в application, и что если я перенесу создание EntityManager  в сам бин только через аннотацию, то есть это одно тоже ?, и ошибка так же вылетать?

или вот еще, может тогда перенести EntityManager  в JPABean который в application, то есть он будет возвращать не EntityManagerFactory, а сразу EntityManager, причем всегда один и тот же, так как закеширован.. так правильно вообще делать ?

Это сообщение отредактировал(а) aol - 25.10.2008, 01:53
PM MAIL   Вверх
powerOn
Дата 25.10.2008, 02:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  02:50 Найти цитируемый пост)

или вот еще, может тогда перенести EntityManager  в JPABean который в application, то есть он будет возвращать не EntityManagerFactory, а сразу EntityManager, причем всегда один и тот же, так как закеширован.. так правильно вообще делать ?


В application scope его не следует создавать, ведь так к нему будут обращаться потоки параллельно из нескольких запросов, что есть плохо. Желательно, сто бы каждый request имел свой EntityManager. На крайний случай можно создавать его в Session scoped бине, но только если этого требует логика.

Цитата(aol @  25.10.2008,  02:50 Найти цитируемый пост)
до конца не понимаю тогда в чем будет разница, то что я сейчас создаю EntityManager из обьекта который висит постоянно в application, и что если я перенесу создание EntityManager  в сам бин только через аннотацию, то есть это одно тоже ?,


Если будете сами создавать EntityManager, то
Цитата(powerOn @  25.10.2008,  02:36 Найти цитируемый пост)
придется самостоятельно следить за транзакциями (открывать, закрывать), а во время Unit такой подход будет лишней палкой в колесе.




--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



ага, то есть если в бине будет 
@PersistenseContext(unitName="portalJPA")
EntityManager em;
то это значит что я его не сам создаю ?

то есть это не совсем одно и тоже как было раньше 
EntityManager em = jpaBean.getEMF().createEntityManager();
PM MAIL   Вверх
powerOn
Дата 25.10.2008, 02:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  03:23 Найти цитируемый пост)
то это значит что я его не сам создаю ?


совершенно верно. его создаст контейнер и инжектирует в бин.

p.s.: только что попробовал создать ear проект который содержит ejb модуль с EJB бином и web модуль с JSF страницей и managed bean-ом. EJB в JSF бины инжектируются, проверено.



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



убрал из всех бинов которые писали в бд
Код

EntityManager em = jpaBean.getEMF().createEntityManager();

и добавил к ним поле 
Код

@PersistenceContext(unitName = "portalJPA")
private EntityManager em;

из faces-config.xml тоже убрал все записи про JPABean
при попытке деплоя ear такая вот ошибка

Deploying application in domain failed; The persistence-context-ref-name [portal.db.ContractManager/em] in module [] resolves to a persistence unit called [portalJPA] which is of type RESOURCE_LOCAL. Only persistence units with transaction type JTA can be used as a container managed entity manager. Please verify your application.

вот мой persistance.xml
Код

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
  <persistence-unit name="portalJPA" transaction-type="RESOURCE_LOCAL">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <class>portal.model.rumor.User</class>
    <class>portal.model.rumor.document.Contract</class>
    <class>portal.model.rumor.Advertiser</class>
    <properties>
      <property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/portal?characterEncoding=UTF-8"/>
      <property name="toplink.jdbc.user" value="root"/>
      <property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="toplink.jdbc.password" value="1"/>
      <property name="toplink.ddl-generation" value="create-tables" />
      <property name="toplink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>


Это сообщение отредактировал(а) aol - 25.10.2008, 02:48
PM MAIL   Вверх
aol
Дата 25.10.2008, 03:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



под утро уже не вижу что сервак хочет )
фсе деплоиться хорошо, но вот при доступе к базе, теперь фсегда ошибка java.lang.IllegalStateException

да, и то есть теперь необходимости нет в постоянно
      em.getTransaction().begin();
      em.persist(user);
      em.getTransaction().commit();

нужно сразу 
      em.persist(user);
или
      em.refresh(user);
или тд..


PM MAIL   Вверх
powerOn
Дата 25.10.2008, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  03:47 Найти цитируемый пост)
при попытке деплоя ear такая вот ошибка

Deploying application in domain failed; The persistence-context-ref-name [portal.db.ContractManager/em] in module [] resolves to a persistence unit called [portalJPA] which is of type RESOURCE_LOCAL. Only persistence units with transaction type JTA can be used as a container managed entity manager. Please verify your application.


поменяйте в persistance.xml:
Код

<persistence-unit name="portalJPA" transaction-type="RESOURCE_LOCAL">


на
Код

<persistence-unit name="portalJPA" transaction-type="JTA">



Цитата(aol @  25.10.2008,  04:44 Найти цитируемый пост)
да, и то есть теперь необходимости нет в постоянно
      em.getTransaction().begin();
      em.persist(user);
      em.getTransaction().commit();

нужно сразу 
      em.persist(user);
или
      em.refresh(user);
или тд..


Да, теперь не нужно вызывать  em.getTransaction().begin(); или em.getTransaction().commit();. Commit произойдет автоматически. А что бы откатит транзакцию, придется получить ссылку на SessionContext через инъекцию:
Код

@Resource
private SessionContext sessionContext;

и вызывать
Код

sessionContext.setRollbackOnly();


И еще, не забудьте использовать аннотации @TransactionAttribute на методах EJB, что бы отметить необходимую логику транзакции.





--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



на JTA уже поменял

как понимаю sessionContext.setRollbackOnly();
должно быть в блоке catch/finally метода где persist.()
@TransactionAttribute тоже на методах где просходит persist.().. ?

PM MAIL   Вверх
powerOn
Дата 25.10.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Цитата(aol @  25.10.2008,  14:04 Найти цитируемый пост)
как понимаю sessionContext.setRollbackOnly();
должно быть в блоке catch/finally метода где persist.()


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

Цитата(aol @  25.10.2008,  14:04 Найти цитируемый пост)
@TransactionAttribute тоже на методах где просходит persist.().. ?


Почитайте в документации об аннотации @TransactionAttribute и её параметрах. Так же проанализируйте логику вашей программы, где и как должны работать транзакции.  Уже в зависимости от этого, расставляйте аннотации. В частности, для persists() транзакция вам точно потребуется.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



методы проаннотировал как @TransactionAttribute(value = REQUIRES_NEW)
получаю ошибку javax.persistence.TransactionRequiredException

заметил что ошибка возникает на persis, find, тд..
на запросах типа  Query query = em.createNamedQuery("findUserByEmail"); все нормально

    






PM MAIL   Вверх
powerOn
Дата 25.10.2008, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



а если REQUIRED попробовать? (ну или @TransactionAttribute без параметров указать, тогда будет выставлен тип REQUIRED по умолчанию).


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



делал по разному, и REQUIRED  и без параметров тоже

PM MAIL   Вверх
powerOn
Дата 25.10.2008, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



у меня такой код отработал без ошибок:

Код

@Stateless(name = "NewSessionBean")
public class NewSessionBean implements NewSessionLocal
{
    @PersistenceContext(unitName = "EnterpriseApplication1-ejbPU")
    private EntityManager em;

    @TransactionAttribute
    public String getMessage()
    {
        Query query = em.createNamedQuery("getSimpleEntities"); // @NamedQuery(name="getSimpleEntities", query="select s from SimpleEntity s") 
        SimpleEntity entity = new SimpleEntity("This is just a simple message!");
        em.persist(entity);
        List<SimpleEntity> resultList = (List<SimpleEntity>) query.getResultList();
        return resultList.get(0).getMessage();
    }
}


Добавлено через 4 минуты и 20 секунд
Кстати, смотрел непосредственно в БД, новая запись там появляется. Т.е. persist и commit отрабатывают.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 25.10.2008, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



да, тоже самое, только без implements Local
быть может что то не инджектиться, но что и когда не знаю

PM MAIL   Вверх
powerOn
Дата 25.10.2008, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Ваш EJB компонент должен имплементировать локальный интерфейс. У меня было сделано так:
Код

import javax.ejb.Local;

@Local
public interface NewSessionLocal {
    public String getMessage();
}


метод getMessage объявлен в локальном интерфейсе и будет управляться контейнером, т.е. будет выполнятся с учетом транзакций и секьюрити. 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 26.10.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



добавил
Код

@Local
public interface UserManagerLocal {
  public boolean findUserByEmail(String email);
  public boolean addUser(User user);
  public User findUser(String email, String password);
}


Код

@Stateless(name = "UserManager")
public class UserManager implements UserManagerLocal{
  
  @PersistenceContext(unitName = "portalJPA")
  private EntityManager em;

  @TransactionAttribute
  public User findUser(String email, String password){
    User user = null;
    try{
      Query query = em.createNamedQuery("checkUser");
      query.setParameter("email", email);
      query.setParameter("password", password);
      user = (User)query.getSingleResult();
    }catch (NoResultException ex){
    }
    return user;
  }

  @TransactionAttribute
  public boolean findUserByEmail(String email){
    boolean ret = false;
    try{
      Query query = em.createNamedQuery("findUserByEmail");
      query.setParameter("email", email);
      if(query.getResultList().size() > 0) ret = true;
    }finally {
    }
    return ret;
  }

 @TransactionAttribute
  public boolean addUser(User user){
    boolean ret = false;
    try{
      user.setSince(new Date());
      em.persist(user);
      ret = true;
    }finally {
    }
    return ret;
  }


в классе
public class UserAuthBean {
,методы которого вызываются с jsf
пробовал описать

private UserManager userManager;
if(userManager.addUser(user)) {...

так и 

private UserManagerLocal userManager;
if(userManager.addUser(user)) {...

получаю javax.persistence.TransactionRequiredException

возможно нужно что то еще проаннотировать.

нужно ли аннотировать

public class UserAuthBean {
@EJB
private UserManager userManager; ?





Это сообщение отредактировал(а) aol - 26.10.2008, 14:40
PM MAIL   Вверх
powerOn
Дата 26.10.2008, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Если EJB создан как:

Код

@Stateless(name = "NewSessionBean")
public class NewSessionBean implements NewSessionLocal
{
...
}


в бине JSF пишется инъекция таким образом:

Код

    @EJB(beanName = "NewSessionBean")
    private NewSessionLocal newSessionLocal;



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 26.10.2008, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



получаю вот что теперь 
com.sun.enterprise.deployment.backend.IASDeploymentException: Error loading deployment descriptors for module [Web] -- Error: Unresolved <ejb-link>: UserManager
или теперь нужно фсе entity описать в ejb-jar.xml ?
немного не понимаю что происходит
PM MAIL   Вверх
powerOn
Дата 26.10.2008, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



А что Вы кстати деплоите? И на какой сервер.
У меня ear архив, который содержит jar с EJB компонентами и war с web-приложением.
Прикрепил свой проект (для NetBeans IDE).






Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  EnterpriseApplication1.zip 45,21 Kb


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 26.10.2008, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



сервер sun app server, деплою из идеи, ear, идея помещает файл ear в каталог сервера autodeploy.
по смыслу вроде тоже самое что и у вас. 
разницу увидел в том, что у меня jsf страница вызывает методы у своего бина, который в свою очередь вызывает промежуточный бин у которого есть @EJB(beanName = "UserManager") а уже он обращается к UserManager

пробовал деплоить вручную из вебконсоли, ошибка при деплое war 
Deploying application in domain failed; Error loading deployment descriptors for module [Web] -- Error: Unresolved : UserManager Error loading deployment descriptors for module [Web] -- Error: Unresolved : UserManager 

выслал вам на email, может там виднее )
сюда не помещается

Это сообщение отредактировал(а) aol - 26.10.2008, 19:51
PM MAIL   Вверх
powerOn
Дата 26.10.2008, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



У меня такая ошибка возникает если модули EJB и WAR деплоить по отдельности.

Добавлено через 1 минуту и 31 секунду
сейчас посмотрю Ваши наработки.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
powerOn
Дата 26.10.2008, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



Я посмотрел исходники и не совсем понял, что же получается после сборки. Такое ощущение, что это архив со структурой war-файла, а не ear с двумя отдельными модулями. Почему-то классы EJB и JSF бинов находится в одной подпапке исходников. Вышлите то, что получится после сборки.

Добавлено через 4 минуты и 24 секунды
прикрепил свою сборку

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  EnterpriseApplication1.ear 11,34 Kb


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
aol
Дата 31.10.2008, 02:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 23.10.2008

Репутация: нет
Всего: нет



в проблеме разобрались, спасибо powerOn`у 
если в коротко, то я создавал обьект EntityManager из закешированного в application обьекте типа EntityManagerFactory, и получал каждый раз новый, приходилось транзакциями тоже рулить, хотя и не очень сильно, сейчас же все это делает контейнер вообще без нашей помощи,  описывается с помощью аннотаций.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0840 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.