实体不是已知的实体类型
Entity is not a known entity type
我尝试使用 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;
}
}
因为:
Severe: Exception while deploying the app [uuf-onlineshop-ear] :
Invalid ejb jar [uuf-onlineshop-ejb-1.0-SNAPSHOT.jar]: it contains
zero ejb. Note:
A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean.
EJB3+ entity beans (@Entity) are POJOs and please package them as library jar.
If the jar file contains valid EJBs which are annotated with EJB component level annotations (@Stateless, @Stateful, @MessageDriven,
@Singleton), please check server.log to see whether the annotations were processed properly.
如果我向实体添加 @Stateful 注释,我就可以部署该应用程序。
但是,当我随后访问 RegisterController 时,在保留 Customer 时抛出以下异常:
exception:>
javax.servlet.ServletException: java.lang.IllegalArgumentException:
Object:
ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188
is not a known entity type. root cause
javax.faces.el.EvaluationException:
java.lang.IllegalArgumentException: Object:
ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188
is not a known entity type.
控制器:
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";
}
}
知道问题出在哪里吗?
您的 @Entity
实体 bean 一切正常。不要修改它。使其成为 EJB 确实会导致所描述的异常,因为 EJB 容器围绕 class 创建了一个代理,而后者又不被识别为 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";
}
// ...
}
请注意,您不需要手动 fiddle 处理真实 EJB 中的用户事务。只有 Customer
上的 @Inject
有点奇怪。我不确定 @Data
的作用,但如果它与 CDI 的 @Model
注释具有相同的效果,那么就可以了。否则请前往下面的第二个 link 以获取具体示例和更多 links.
另请参阅:
- When is it necessary or convenient to use Spring or EJB3 or all of them together?
我尝试使用 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;
}
}
因为:
Severe: Exception while deploying the app [uuf-onlineshop-ear] : Invalid ejb jar [uuf-onlineshop-ejb-1.0-SNAPSHOT.jar]: it contains zero ejb. Note:
A valid ejb jar requires at least one session, entity (1.x/2.x style), or message-driven bean.
EJB3+ entity beans (@Entity) are POJOs and please package them as library jar.
If the jar file contains valid EJBs which are annotated with EJB component level annotations (@Stateless, @Stateful, @MessageDriven, @Singleton), please check server.log to see whether the annotations were processed properly.
如果我向实体添加 @Stateful 注释,我就可以部署该应用程序。 但是,当我随后访问 RegisterController 时,在保留 Customer 时抛出以下异常:
exception:> javax.servlet.ServletException: java.lang.IllegalArgumentException: Object: ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188 is not a known entity type. root cause
javax.faces.el.EvaluationException: java.lang.IllegalArgumentException: Object: ch.uufstellend.onlineshop.model.__EJB31_Generated__Customer__Intf___302872188 is not a known entity type.
控制器:
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";
}
}
知道问题出在哪里吗?
您的 @Entity
实体 bean 一切正常。不要修改它。使其成为 EJB 确实会导致所描述的异常,因为 EJB 容器围绕 class 创建了一个代理,而后者又不被识别为 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";
}
// ...
}
请注意,您不需要手动 fiddle 处理真实 EJB 中的用户事务。只有 Customer
上的 @Inject
有点奇怪。我不确定 @Data
的作用,但如果它与 CDI 的 @Model
注释具有相同的效果,那么就可以了。否则请前往下面的第二个 link 以获取具体示例和更多 links.
另请参阅:
- When is it necessary or convenient to use Spring or EJB3 or all of them together?