2016-03-09 4 views
0

EDIT Итак, я переключился с Glassfish на Wildfly и использовал EclipseLink 2.5. Этот код перестает работать, когда я переключаюсь, при этом возникают проблемы. По какой-то причине диспетчер объектов был создан с локальными транзакциями ресурсов.Суть JPA не сохраняется в DB

Я пробовал много вещей, но когда я переключился на Hibernate EM, все работало нормально. END EDIT

Я использую Wildfly 10 и EclipseLink JPA иметь простой Stateless EJB сохранить запись в базе данных. Методы здесь:

Этот компонент отмечен @Stateless

@POST 
@Override 
@Consumes({"application/xml", "application/json"}) 
public void create(Actor entity) { 
    L.info("Creating {}", entity); 
    super.create(entity); 
    L.info("Created"); 
} 

Вот метод абстрактного родителя:

public void create(T entity) { 
    //getEntityManager().getTransaction().begin(); 
    getEntityManager().persist(entity); 
    //getEntityManager().flush(); 
    //getEntityManager().getTransaction().commit(); 
} 

Если я раскомментировать транзакционный код, он работает.

Если я добавляю аннотацию транзакции, она не работает.

Как это, он не работает.

Почему? Я, хотя EJBs получил транзакции, управляемые контейнером, и что это должно быть автоматически зафиксировано. Вот мое упорство определение единицы:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="net.mikeski_auth_war_0.1.0-SNAPSHOTPU" transaction-type="JTA"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <jta-data-source>java:jboss/datasources/PostgresqlDS</jta-data-source> 
    <class>entities.Actor</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
    <properties> 
     <property name="eclipselink.weaving" value="false"/> 
     <property name="eclipselink.weaving.fetchgroups" value="false"/> 
     <property name="javax.persistence.schema-generation.database.action" value="create"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

Я знаю, что моя сущность хорошо, потому что, если я добавлю некоторую БД находки методы работы, и если я получаю транзакции правильных вставок работают. Что мне не хватает?

+0

попробуйте пометить его как @Transactional –

+0

Можете ли вы опубликовать файл контекста приложения для аннотации транзакций – Sanj

+0

не работает. Я пробовал его по методу абстрактного класса и по методу реализации и как, так и '@TransactionManagement (TransactionManagementType.CONTAINER)' в классе – mikeb

ответ

1

Я бы ожидал, что вы передадите объект в EJB Stateless, даже если этот EJB не делает ничего, кроме вызова em.persist для вас. Здесь вы смешиваете функциональные возможности, вы делаете REST для работы EJB, и могут быть вещи, которые вы (и я) еще не полностью поняли. Кроме того, у service layer безстоящего ejb, по-видимому, были бы другие функции, поэтому это, конечно, не пустая трата.

@Inject ActorService actorService; 

@POST 
@Consumes({"application/xml", "application/json"}) 
public void create(Actor entity) { 
    L.info("Creating {}", entity); 
    actorService.create(entity); 
    L.info("Created"); 
} 

и, предположительно:

@Stateless 
public class ActorService { 
    @Inject private EntityManager em; 

    public create(Actor actor) { 
     em.persist(actor); 
    } 
    .. the rest of the actor service layer 
} 

Я думаю, что более важно понимать ожидаемый способ сделать вещи, чем понять, почему необычное не работает.

Надеюсь, это поможет.

+0

Я использую эту настройку, потому что это шаблон Netbeans для генерации сервисов REST от объектов. Они используют аннотацию @PersistenceContext для создания EM. Как я могу построить EntityManager в этом случае, чтобы сделать его доступным? – mikeb

+0

Переключение с EclipseLink на Hibernate JPA работает – mikeb

+0

Привет, Mikeb, я бы сказал, продолжайте использовать @PersistenceContext в своем безэкрановном ejb. Кроме того, да, я обычно использую класс утилиты Resources, который создает PersistenceContext для инъекций, как это делается во всех [образцах Wildfly] (https://github.com/wildfly/quickstart/blob/10.x/kitchensink/src /main/java/org/jboss/as/quickstarts/kitchensink/util/Resources.java). Кроме того, я думаю, что спящий режим намного более зрелый, чем EclipseLink. –

0

Я думаю, что инъекция entityManager внутри класса bean, помеченного @Stateless, должна работать.

Если вы получаете entitymanager в каком-либо другом классе (родительский класс), попробуйте получить его из entityManagerFactory вместо прямого впрыска. Вы уже делаете это в суперклассе или у вас есть геттер для инъекций em.

Возможно, проблема с версией java ee as discussed in an answer here Я думаю, что ответ должен быть полезен.

Таким образом, я согласен с материалами Николаса о разделении обязанностей.

+0

ОК, так как мне создать диспетчер объектов, если не из аннотации @PersistenceContext? – mikeb

+0

@mikeb Ссылка в моем ответе имеет соответствующий код. Или вы можете использовать подход, который Николя упоминает со своим примером кода, используя Inject аннотацию – Atul

+0

Я тоже пробовал, и это не сработало. Я переключился на Hibernate JPA, и все сработало отлично. Я думаю, это EclipseLink и Wildfly. – mikeb