如何让EntityManager可注射?

时间:2012-07-25 14:53:03

标签: glassfish nosql java-ee-6 code-injection entitymanager

我有以下代码:

MonsterEJB.java:

package model;

import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

@Stateless
@LocalBean
@Named
public class MonsterEJB 
{
    @PersistenceUnit(unitName="mongo")
    private EntityManager em;

    @Inject
    private Monster injectableMonster;

    public MonsterEJB() 
    {

    }

    public void create() 
    {
        em.getTransaction().begin();
        Monster en = new Monster();
        en.setDescription(injectableMonster.getDescription());
        em.persist(en);
        em.getTransaction().commit();
    }

    public List<Monster> getList() 
    {
        Query query = em.createQuery("Select m from Monster m");
        List<Monster> Monsters = query.getResultList();

        return Monsters;
    }

    public void remove()
    {
        em.getTransaction().begin();
        Monster en = em.find(Monster.class, injectableMonster.getId());
        em.remove(en);
        em.getTransaction().commit();
    }

    public void update() 
    {
        em.getTransaction().begin();
        Monster en = em.find(Monster.class, injectableMonster.getId());
        en.setDescription(injectableMonster.getDescription());
        em.getTransaction().commit();
    }
}

Monster.java:

package model;

import java.io.Serializable;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.persistence.*;

import org.eclipse.persistence.nosql.annotations.*;

@Entity
@Named
@RequestScoped
@NoSql(dataFormat = DataFormatType.MAPPED)
public class Monster implements Serializable 
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Field(name = "_id")
    private String id;

    @Version
    private long version;

    @Basic
    private String description;

    public Monster() 
    {

    }

    public String getId() 
    {
        return id;
    }

    public void setId(String id) 
    {
        this.id = id;
    }

    public String getDescription() 
    {
        return description;
    }

    public void setDescription(String description) 
    {
        this.description = description;
    }

    @Override
    public String toString() 
    {
        return "Monster [id=" + id + ", version=" + version + ", description="+ description;
    }
}

的persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
        version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="mongo" transaction-type="RESOURCE_LOCAL">
        <class>model.Monster</class>
        <properties>
            <property name="eclipselink.target-database" value="org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"/>
            <property name="eclipselink.nosql.connection-spec" value="org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"/>
            <property name="eclipselink.nosql.property.mongo.port" value="27017"/>
            <property name="eclipselink.nosql.property.mongo.host" value="localhost"/>
            <property name="eclipselink.nosql.property.mongo.db" value="MonsterDatabase"/>
            <property name="eclipselink.logging.level" value="FINEST"/>
        </properties>
    </persistence-unit>
</persistence>

Show.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

<ui:composition template="WEB-INF/templates/BasicTemplate.xhtml">

    <ui:define name="header">
        <div style="width:100%;font-size:36px;line-height:48px;background-color:navy;color:white">Showing Monsters</div>
    </ui:define>

    <ui:define name="content">
        <h:dataTable var="f2" value="#{MonsterEJB.list}">
            <h:column>#{f2.id}, #{f2.description}</h:column>
        </h:dataTable>
    </ui:define>

</ui:composition>
</html>

网页显示错误

type Exception report

message

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
root cause

javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
root cause

javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
root cause

javax.ejb.CreateException: Could not create stateless EJB
root cause

java.lang.IllegalStateException: Exception attempting to inject Env-Prop: model.MonsterEJB/em@Field-Injectable Resource. Class name = model.MonsterEJB Field name=em@java.lang.String@@@ into class model.MonsterEJB
root cause

com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: model.MonsterEJB/em@Field-Injectable Resource. Class name = model.ElnotEJB Field name=em@java.lang.String@@@ into class model.MonsterEJB
root cause

java.lang.IllegalArgumentException: Can not set javax.persistence.EntityManager field model.MonsterEJB.em to com.sun.enterprise.container.common.impl.EntityManagerFactoryWrapper

问题: 如何让我的MonsterEJB.java注入一个带NoSQL的EntityManager?

2 个答案:

答案 0 :(得分:3)

尝试使用@PersistenceContext而不是@PersistenceUnit

答案 1 :(得分:1)

我不确定这是您的例外的原因,但是您的MonsterEJB课程同时注明为@Named@Stateless@Named用于定义JSF Managed Bean@Stateless Enterprise Java Beans,这些是不同的事情。

使用一个或另一个注释。

此外,Monster类同时定义为:EntityManagedBean@Named注释,以及作为CDI bean {{1注释。这也没有意义。

我建议学习一些Java EE 6教程(如this)以澄清这些概念。