【问题标题】:Entity is not a known entity type实体不是已知的实体类型
【发布时间】:2016-02-27 16:00:43
【问题描述】:

我尝试用 JSF 和 Java EE 在 java 中制作一个简单的 Java EE 应用程序。

我无法部署以下客户实体:

package ch.uufstellend.onlineshop.model;

import java.io.Serializable;
import javax.ejb.Stateful;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import lombok.Data;

@Entity
@Data
@Table(name = "CUSTOMER")
@NamedQuery(
        name = "Customer.findAll",
        query = "SELECT c FROM Customer c")
public class Customer implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Long id;

    private String email;

    private String password;

    public Customer() {
    }

    @Override
    public String toString() {
        return id + "-" + email + "-" + password;
    }
}

因为:

严重:部署应用程序时出现异常 [uuf-onlineshop-ear] : 无效的 ejb jar [uuf-onlineshop-ejb-1.0-SNAPSHOT.jar]:它包含 零ejb。注意:

  1. 有效的 ejb jar 至少需要一个会话、实体(1.x/2.x 样式)或消息驱动 bean。

  2. EJB3+ 实体 bean (@Entity) 是 POJO,请将它们打包为库 jar。

  3. 如果 jar 文件包含使用 EJB 组件级别注释(@Stateless、@Stateful、@MessageDriven、 @Singleton),请检查 server.log 以查看注释是否被正确处理。

如果我向实体添加@Stateful 注释,我就可以部署应用程序。 但是当我访问 RegisterController 时,在持久化客户时会引发以下异常:

例外:> javax.servlet.ServletException:java.lang.IllegalArgumentException: 目的: ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188 不是已知的实体类型。根本原因

javax.faces.el.E​​valuationException: java.lang.IllegalArgumentException:对象: ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188 不是已知的实体类型。

控制器:

package ch.uufstellend.onlineshop;

import ch.uufstellend.onlineshop.model.Customer;
import java.io.Serializable;

import javax.annotation.Resource;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import lombok.Getter;
import lombok.Setter;

@Named
@RequestScoped
public class RegisterController implements Serializable {

    private static final long serialVersionUID = 1L;

    @PersistenceUnit
    private EntityManagerFactory emf;

    @Resource
    private UserTransaction ut;

    @Inject
    @Getter
    @Setter
    private Customer customer;


    public String persist() {
        try {
            ut.begin();
            EntityManager entityManager = emf.createEntityManager();
            entityManager.persist(customer); // HERE the error is thrown
            ut.commit();
            FacesMessage m = new FacesMessage("Succesfully registered!", "Your email was saved under id " + customer.getId());
            FacesContext.getCurrentInstance().addMessage("registerForm", m);
        } catch (NotSupportedException | SystemException | RollbackException | HeuristicMixedException | HeuristicRollbackException | SecurityException | IllegalStateException e) {
            e.printStackTrace();
            FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_WARN, e.getMessage(), e.getCause().getMessage());
            FacesContext.getCurrentInstance().addMessage("registerForm", m);
        }
        return "/register.jsf";
    }
}

知道问题出在哪里吗?

【问题讨论】:

    标签: jsf ejb


    【解决方案1】:

    您的 @Entity 实体 bean 一切正常。不要修改它。使其成为 EJB 确实会导致所描述的异常,因为 EJB 容器围绕该类创建了一个代理,而该代理又不被识别为 JPA 实体。

    您的 @Named 托管 bean 是错误的。它与 EJB 职责(持久性和事务管理)紧密结合。将 EJB 职责拆分为真正的 @Stateless 会话 bean,并让托管 bean 调用它。

    @Stateless
    public class RegisterService {
    
        @PersistenceContext
        private EntityManager entityManager;
    
        public void persist(Customer customer) {
            entityManager.persist(customer);
        }
    
    }
    
    @Named
    @RequestScoped
    public class RegisterController {
    
        @Inject
        private Customer customer;
    
        @EJB
        private RegisterService registerService;
    
        public String submit() {
            FacesMessage m;
    
            try {
                registerService.persist(customer);
                m = new FacesMessage("Succesfully registered!", "Your email was saved under id " + customer.getId());
            } catch (Exception e) {
                m = new FacesMessage(FacesMessage.SEVERITY_WARN, e.getMessage(), e.getCause().getMessage());
            }
    
            FacesContext.getCurrentInstance().addMessage("registerForm", m);
            return "/register.jsf";
        }
    
        // ...
    }
    

    请注意,您不需要在真正的 EJB 中手动处理用户事务。只有Customer 上的@Inject 有点奇怪。我不确定@Data 是做什么的,但如果它与CDI 的@Model 注释具有相同的效果,那就没关系了。否则,请转到下面的第二个链接以获取具体示例和更多链接。

    另见:

    【讨论】:

    • 最后的小问题:我有一个 ejb 和一个 web maven 项目。我应该把RegisterService放在哪里?它是否像 DAO 一样,应该放在所有与数据相关的东西所在的 EJB 中? PS,@Data 是 Lombok 注释并自动生成 setter、getter、覆盖 toString + equals 和 hashCode 方法:projectlombok.org
    • 你应该把 EJB 类放在 EJB 项目中,是的。
    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    相关资源
    最近更新 更多