实体不是已知的实体类型

时间:2015-11-25 00:57:59

标签: jsf ejb

我尝试使用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.   
  3. EJB3 +实体bean(@Entity)是POJO,请将它们打包为库jar。

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

  6.   

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

  

例外产品:>   javax.servlet.ServletException:java.lang.IllegalArgumentException:   宾语:   ch.uufstellend.onlineshop.model .__ EJB31_Generated__Customer__Intf___302872188   不是已知的实体类型。根本原因

     

javax.faces.el.E​​valuationException:   java.lang.IllegalArgumentException:Object:   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";
    }
}

知道问题出在哪里?

1 个答案:

答案 0 :(得分:3)

你的@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中手动调整用户事务。只有@Inject上的Customer有点奇怪。我不确定@Data的作用,但如果它与CDI的@Model注释具有相同的效果,那就没关系。否则,请转到下面的第二个链接,了解具体示例和更多链接。

另见: