Seam 2.2 с jboss 5 без ejb не може да инжектира entityManager

ETA обяснение какво трябва да прави това. Служителят трябва да следи дейностите за 2 седмици.

Всяка седмица (tqiActivitySheetActionBean) съдържа 7 дни (tqiDayActionBean).

Всеки ден съдържа задачи за този ден (tqiTasks)

Задачите се показват една седмица наведнъж (така че служителят може да превключва между тази и миналата седмица).

Това, което направих, беше да използвам enum за итерация през седмицата - създава dataTable от tqiActivitySheetActionBeans и итерира върху тези във вложена dataTable.

Служителят трябва да може да добавя, изтрива и редактира задачи за всеки ден на място (в таблицата с данни). Увих tqiTasks в tqiDayActionBean, за да ги групирам.

Публикувах това на уебсайта на Seam, но не получавам никакви ухапвания, опитах всичко, което знам, и някои неща, които не мога, за да подействам, но засега няма радост. Има информация за конфигурация за Jboss 5 с използване на EJB, Jboss 4 без. Имам експлодирал WAR с помощта на Jboss 5 и Seam 2.2.0 и без EJB. Не мога да инжектирам entityManager в моите POJO за действие. Опитах се да премахна справката за persistence-unit-ref-name от web.xml, добавих и премахнах

<transaction:entity-transaction /> 
<transaction:ejb-transaction />

тагове от components.xml (със и без entity-manager="#{entityManager}") . Приложението няма да се зареди, когато използвам някое от тези. Използвани са стойностите по подразбиране и са ги кодирани една по една. Все още не мога да накарам това да работи. В момента използвам тази конфигурация:

persistence.xml:

<persistence-unit name="myEmployee" transaction-type="JTA">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/myEmployeeDatasource</jta-data-source>
      <properties>
         <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
         <property name="hibernate.hbm2ddl.auto" value="validate"/>
         <property name="hibernate.show_sql" value="true"/>
         <property name="hibernate.format_sql" value="true"/> 
         <property name="hibernate.default_schema" value="MY_PROD"/>
         <!-- Only relevant if Seam is loading the persistence unit (Java SE bootstrap) -->
         <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<!-- this binds emf to jndi under java namespace - but only for jboss prior to 5.0 - I shouldn't need this. -->
<property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactories/myEmployee"/>
      </properties>
   </persistence-unit>

компоненти.xml:

<persistence:managed-persistence-context name="entityManager"
persistence-unit-jndi-name="java:/EntityManagerFactories/myEmployee"
auto-create="true"/>

Това се внедрява и стартира правилно, но entityManager все още е нула.

Имам куп класове EntityHome в същия пакет, те могат да използват entityManager без проблем. Всички документи, които разгледах, посочват, че трябва да мога да инжектирам entityManager, проследих информацията за конфигурацията от страницата с документи на Seam, книгата Seam in Action и уикито на Seam за JBoss 5 (Seam wiki)

Зададох точки на прекъсване в класа ManagedPersistence - където изглежда, че имам entityManager точно до момента, в който искам да го използвам, добавих анотации @Transactional към класа и метода. Все още нищо. Мога да получа EM с помощта на

(EntityManager)Component.getInstance("entityManager")

Но след това нямам транзакционен достъп до основния entityBean и завършвам с хибернация LazyInitializationExceptions. Използвам Seam вече почти година и все още не съм накарал това да работи. Досега използването на метода Component работеше, но трябва да има нещо фундаментално нередно с нашата настройка, че не мога да накарам инжекцията да работи. Ще се радвам на всяка помощ.

ETA код за потребителски класове.

Класът на обекта е TQITask. Класът TQIDayActionBean трябва да обработва CRUD за група от TQITasks за един ден, TQIActivitySheetActionBean обработва TQIDayActionBeans за една седмица.

бийн обект:

@Entity
@Table(name = "TQI_TASK")
@Name("tqitask")
public class TqiTask implements java.io.Serializable {

    static Logger log = Logger.getLogger(TqiTask.class);
    private Integer sysid;
    private TqiActivitySubtype tqiActivitySubtype;
    private TqiActivityType tqiActivityType;
// ... more fields, getters and setters

dayActionBean (задачи за дни):

@Name("tQIDayActionBean")
@Transactional(TransactionPropagationType.REQUIRED) //this is latest attempt
@Scope(ScopeType.CONVERSATION)
public class TQIDayActionBean implements Serializable {
    static Logger log = Logger.getLogger(TQIDayActionBean.class);


    @In(required=true)
    EntityManager entityManager;
//this doesn't work either
        @DataModel("tqiTasksForOneDay")
    @Out(required = false)
    private List<TqiTask> tqiTasksForOneDay;

// .... more stuff
// method that should get an entityManager
/**
     * tasks are children of tqiActivitySheet, info we need is in tqiActivitySheetV, so use peopleSoftIdSelected and weekSelected.weekSysid
     * to get the tqiActivitySheet sysid needed to load the right tasks
     *  TODO for now lets just get it straight from the db
     */
    @SuppressWarnings("unchecked")
    @Begin(flushMode=FlushModeType.MANUAL)
    public void generateTasksForDayOfWeek() {
        log.debug("date to search for: " + this.tqiTaskDate);

        this.tqiTasksForOneDay = this.entityManager.createQuery("SELECT t from TqiTask t  where t.workDate = ?1 AND t.activitySheetSysid = ?2 order by t.sysid")
        .setParameter(1, this.tqiTaskDate).setParameter(2, this.activitySheetSysid).getResultList();
    }

getter/setters etc ...

activitySheetActionBean(седмичен денActionBeans):

/**
 * handle the activity sheet weekly code generation here
 */
@Name("tqiActivitySheetActionBean")
public class TQIActivitySheetActionBean implements Serializable{
    static Logger log = Logger.getLogger(TQIActivitySheetActionBean.class);

// tried it here first  
//  @In
//  EntityManager entityManager;


    @Out(value="tqiDayActionBeansForTheWeek", required=false)
    List<TQIDayActionBean> tqiDayActionBeansForTheWeek;

//  List<DaysOfTheWeek> daysOfTheWeekEnum;

    private BigDecimal currentlySelectedWeekActivitySheetSysid;

    @PostConstruct
    public void init(){
        log.debug("calling init");
        this.tqiDayActionBeansForTheWeek = new ArrayList<TQIDayActionBean>();
        this.updateDataWhenWeekChanges();
    }
 getters/setters more stuff ....

person gebuh    schedule 30.08.2011    source източник
comment
Моля, публикувайте кода на класа, в който получавате entityManager, инжектиран като null, и как използвате този клас.   -  person Stefano Travelli    schedule 31.08.2011
comment
готово, помислих си, че може би новият tqiDayActionBean в init причинява проблема, но не мога да инжектирам и това.   -  person gebuh    schedule 31.08.2011
comment
Имате ли други компоненти, при които инжектирането на мениджъра на обекти работи? Как се нарича TQIActivitySheetActionBean? Опитвали ли сте @In(create=true)?   -  person kraftan    schedule 01.09.2011
comment
@kraftan единственото място, където мога да използвам entityManager без да използвам Component.getInstance() е в класовете, които разширяват EntityHome. Опитах се да използвам create=true. TQIActivitySheetActionBean е достъпен от изгледа:<rich:dataTable id="daysOfWeek" var="_daysOfWeek" value="#{tqiActivitySheetActionBean.tqiDayActionBeansForTheWeek}">   -  person gebuh    schedule 01.09.2011


Отговори (1)


Bean с име tQIDayActionBean от клас TQIDayActionBean не може да бъде създаден с new и няма абсолютно никакъв начин да има List<TQIDayActionBean> в приложението.

Този bean, както всеки друг bean, управляван от Seam, може да бъде инжектиран само с @In или инстанциран с Component.getInstance(). Във втория случай (това е с Component.getInstance()) трябва да разберете, че Seam винаги ще връща същия екземпляр, доколкото останете в границите на контекста (в този случай, докато разговорът приключи).

Предлагам ви да преработите кода си, за да отделите стандартен клас TQIDay (без @Name и @Inject), за да моделирате данните, които трябва да управлявате и събирате в множество екземпляри, от TQIActionBean, където можете да инжектирате своя EntityManager.

person Stefano Travelli    schedule 31.08.2011
comment
Благодаря ти, Стефано, можеш ли да разшириш последния си параграф? Ако създам стандартен клас няма ли да имам същия проблем? TQIDayActionBean управлява група от tqiTasks (клас обект). tqiTasks има връзки с други обекти, така че дори и да мога да създам em в TQIActivitySheetActionBean (което не мога, първо опитах това, коментирано е в този клас), как бих избегнал LazyInitializationExceptions, когато свързаните обекти не са свързани ( Получавам ги, когато използвам Component.Instance, освен ако не използвам FetchType.EAGER в tqiTask за свързани полета)? - person gebuh; 01.09.2011
comment
За съжаление не мога да следвам цялата ви логика на приложението. При условие, че не се опитвате да създадете множество екземпляри на Seam bean и не го инстанциирате с new, ако вашият компонентен разговор е с обхват, няма да имате LIE. Също така не забравяйте да започнете разговора. Опитайте с ‹begin-conversation join=true/› във yourpage.page.xml. - person Stefano Travelli; 01.09.2011
comment
Съжалявам, напълно възможно е да правя всичко погрешно. Добавих обяснение какво трябва да прави това зло в горната част. - person gebuh; 01.09.2011