org.hibernate.MappingException:未知实体:domain.ShoppingCart$Proxy$_$$_WeldClientProxy
org.hibernate.MappingException: Unknown entity: domain.ShoppingCart$Proxy$_$$_WeldClientProxy
我遇到了一个奇怪的错误,我无法调试。如果你能仔细阅读细节并向我推荐一些东西,我将不胜感激。
我正在使用 Jboss Server 7.1。
Web 应用程序适用于所有模块。但是当我完成购物车中的产品并执行 "Checkout" 时,它会导致异常。
我提供了几乎所有必需的信息,如果您需要任何其他信息,请告诉我。非常感谢您的友好回复。非常感谢查看我的请求。
项目中包含的库(JBoss自己包含的库除外)
HibernateUtil.java
public static SessionFactory getSessionFactory() {
try{
Configuration conf=new Configuration();
conf.configure("/com/webshop/hb/config/mycfg-mysql.xml");
sessionFactory =conf.buildSessionFactory();
}catch(Exception e){
e.printStackTrace();
}
return sessionFactory;
}
ShoppingCart.java
package domain;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
@Named
@SessionScoped
@Entity
public class ShoppingCart implements Serializable { private static long currentId =1;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private long id;
@Column(name="date")
private Date date;
@ManyToOne
@JoinColumn(name="user")
private User user;
@ElementCollection
private Map<Product, Integer> orders = new HashMap<Product, Integer>();
@Column(name="status")
private OrderStatus status; // String
public ShoppingCart() {
this(new Date());
}
public ShoppingCart(Date date) {
super();
this.id = currentId++; // Simple way of getting an unique id. To be deferred to the DBMS later.
this.date = date;
this.status = OrderStatus.EMPTY;
}
public ShoppingCart(Date date, User user) {
this(date);
this.user = user;
}
public ShoppingCart(Date date, User user, OrderStatus status) {
this(date, user);
if (((status == OrderStatus.COMPLETED) || (status == OrderStatus.PAID)) && (this.getUser() == null)) {
throw new IllegalStateException("No user specified for complete or paid orders");
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Map<Product, Integer> getOrders() {
return orders;
}
public void setOrders(Map<Product, Integer> orders) {
this.orders = orders;
}
public OrderStatus getStatus() {
return status;
}
public void setCompleted(OrderStatus status) throws IllegalStateTransitionException {
if ((status == OrderStatus.COMPLETED) && (this.getUser() == null)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.COMPLETED.toString(), "Customer empty");
}
if ((status == OrderStatus.PAID) && (this.getUser() == null)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.PAID.toString(), "Customer empty");
}
if ((status == OrderStatus.PAID) && (this.getStatus() != OrderStatus.COMPLETED)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.PAID.toString(), "Can only go to paid for completed orders");
}
this.status = status;
}
public long getId() {
return id;
}
public void addToCart(Product product, int amountSelected) {
if (orders.containsKey(product)) {
int amount = orders.get(product);
amount +=amountSelected;
orders.put(product, amount);
}
else {
orders.put(product, amountSelected);
}
}
public void removeFromCart(Product product) {
if (orders.containsKey(product)) {
int amount = orders.get(product);
amount --;
if (amount <= 0) {
orders.remove(product);
}
else {
orders.put(product, amount);
}
}
}
public int getNumberOfItems() {
Set<Product> uniqueProducts = orders.keySet();
int amount = 0;
for (Product aProduct: uniqueProducts) {
amount += orders.get(aProduct);
}
return amount;
}
@Override
public String toString() {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Calendar cal = Calendar.getInstance();
return "Order of " + this.user + ", date " + dateFormat.format(cal.getTime());
}
}
mycfg-mysql.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- <property name="hibernate.bytecode.use_reflection_optimizer">false</property> -->
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
-->
<property name="connection.datasource">java:jboss/datasources/webshopstudent</property>
<property name="hibernate.connection.pool_size">100</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<!-- Automatic schema creation (begin) === -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="current_session_context_class">thread</property>
<mapping class="domain.User"/>
<mapping class="domain.Product"/>
<mapping class="domain.Wax"/>
<mapping class="domain.Miscellaneous"/>
<mapping class="domain.Honey"/>
<mapping class="domain.Flower"/>
<mapping class="domain.ShoppingCart"/>
</session-factory>
</hibernate-configuration>
从购物车结账时出现异常
导致问题的函数
public String confirmOrder() throws IllegalStateTransitionException {
shoppingcart.setUser(userholder.getCurrentUser());
shoppingcart.setCompleted(OrderStatus.COMPLETED);
shoppingcart.setDate(new Date());
// Setting up sessions
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(shoppingcart); // This Line is causing the Exception, I checked by debugging
session.close();
updateStocks();
FacesContext fc = FacesContext.getCurrentInstance();
fc.getELContext().getELResolver().setValue(fc.getELContext(), null, "shoppingCart", null);
//printing Invoice
//writing to file
try {
String content = "Customer Name: " + shoppingcart.getUser().firstName + " " + shoppingcart.getUser().lastName +"\r\n" +
"Address : " + shippingAddress + "\r\n" +
"Date Received: " + shoppingcart.getDate() + "\r\n" +
"Order Items :" + shoppingcart.getOrders() + "\r\n" +
"Money to be received :" + productHolder.subTotal();
// File file = new File("/Users/Vinod/Documents/newfile.txt");
File file = new File("F:/" + shoppingcart.getId() + shoppingcart.getUser().firstName + "invoice.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
System.out.println("Done");
}catch (IOException e) {
e.printStackTrace();
}
return "orderComplete";
}
对我来说,原因很明显:您的 ShoppingCart
实体也是 CDI 托管 bean。我几乎可以肯定你在方法 confirmOrder
:
上方的某处注入了 shoppingcart
@Inject
ShoppingCart shoppingcart;
我说得对吗?如果是,那就是这个原因。
通常 JPA 实体 shouldn't be managed 作为 CDI Beans。这背后的原因是为了防止 BeanManager 执行可能导致 JPA 提供程序中断的操作(因为这导致了您的异常)。
所以请尝试这样的事情:
package domain;
@Entity
public class ShoppingCart implements Serializable {
// ...
}
然后定义另一个 class,它包含上述实体:
package com.some_package;
@Named
@SessionScoped
public class ShoppingCartWrapper {
ShoppingCart store = new ShoppingCart(); // this is your entity
}
这个class可以随便注入。然后保存看起来像:
public String confirmOrder() throws IllegalStateTransitionException {
// ...
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(shoppingCartWrapper.getStore());
session.close();
// ...
}
顺便说一句:个人提示:像这样管理事务 - 我的意思是 "by hand",没有拦截器 容易出错 并且不会使您的代码 干净.
我遇到了一个奇怪的错误,我无法调试。如果你能仔细阅读细节并向我推荐一些东西,我将不胜感激。
我正在使用 Jboss Server 7.1。
Web 应用程序适用于所有模块。但是当我完成购物车中的产品并执行 "Checkout" 时,它会导致异常。
我提供了几乎所有必需的信息,如果您需要任何其他信息,请告诉我。非常感谢您的友好回复。非常感谢查看我的请求。
项目中包含的库(JBoss自己包含的库除外)
HibernateUtil.java
public static SessionFactory getSessionFactory() {
try{
Configuration conf=new Configuration();
conf.configure("/com/webshop/hb/config/mycfg-mysql.xml");
sessionFactory =conf.buildSessionFactory();
}catch(Exception e){
e.printStackTrace();
}
return sessionFactory;
}
ShoppingCart.java
package domain;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
@Named
@SessionScoped
@Entity
public class ShoppingCart implements Serializable { private static long currentId =1;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ID")
private long id;
@Column(name="date")
private Date date;
@ManyToOne
@JoinColumn(name="user")
private User user;
@ElementCollection
private Map<Product, Integer> orders = new HashMap<Product, Integer>();
@Column(name="status")
private OrderStatus status; // String
public ShoppingCart() {
this(new Date());
}
public ShoppingCart(Date date) {
super();
this.id = currentId++; // Simple way of getting an unique id. To be deferred to the DBMS later.
this.date = date;
this.status = OrderStatus.EMPTY;
}
public ShoppingCart(Date date, User user) {
this(date);
this.user = user;
}
public ShoppingCart(Date date, User user, OrderStatus status) {
this(date, user);
if (((status == OrderStatus.COMPLETED) || (status == OrderStatus.PAID)) && (this.getUser() == null)) {
throw new IllegalStateException("No user specified for complete or paid orders");
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Map<Product, Integer> getOrders() {
return orders;
}
public void setOrders(Map<Product, Integer> orders) {
this.orders = orders;
}
public OrderStatus getStatus() {
return status;
}
public void setCompleted(OrderStatus status) throws IllegalStateTransitionException {
if ((status == OrderStatus.COMPLETED) && (this.getUser() == null)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.COMPLETED.toString(), "Customer empty");
}
if ((status == OrderStatus.PAID) && (this.getUser() == null)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.PAID.toString(), "Customer empty");
}
if ((status == OrderStatus.PAID) && (this.getStatus() != OrderStatus.COMPLETED)) {
throw new IllegalStateTransitionException(this.getStatus().toString(), OrderStatus.PAID.toString(), "Can only go to paid for completed orders");
}
this.status = status;
}
public long getId() {
return id;
}
public void addToCart(Product product, int amountSelected) {
if (orders.containsKey(product)) {
int amount = orders.get(product);
amount +=amountSelected;
orders.put(product, amount);
}
else {
orders.put(product, amountSelected);
}
}
public void removeFromCart(Product product) {
if (orders.containsKey(product)) {
int amount = orders.get(product);
amount --;
if (amount <= 0) {
orders.remove(product);
}
else {
orders.put(product, amount);
}
}
}
public int getNumberOfItems() {
Set<Product> uniqueProducts = orders.keySet();
int amount = 0;
for (Product aProduct: uniqueProducts) {
amount += orders.get(aProduct);
}
return amount;
}
@Override
public String toString() {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Calendar cal = Calendar.getInstance();
return "Order of " + this.user + ", date " + dateFormat.format(cal.getTime());
}
}
mycfg-mysql.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- <property name="hibernate.bytecode.use_reflection_optimizer">false</property> -->
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
-->
<property name="connection.datasource">java:jboss/datasources/webshopstudent</property>
<property name="hibernate.connection.pool_size">100</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<!-- Automatic schema creation (begin) === -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="current_session_context_class">thread</property>
<mapping class="domain.User"/>
<mapping class="domain.Product"/>
<mapping class="domain.Wax"/>
<mapping class="domain.Miscellaneous"/>
<mapping class="domain.Honey"/>
<mapping class="domain.Flower"/>
<mapping class="domain.ShoppingCart"/>
</session-factory>
</hibernate-configuration>
从购物车结账时出现异常
导致问题的函数
public String confirmOrder() throws IllegalStateTransitionException {
shoppingcart.setUser(userholder.getCurrentUser());
shoppingcart.setCompleted(OrderStatus.COMPLETED);
shoppingcart.setDate(new Date());
// Setting up sessions
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(shoppingcart); // This Line is causing the Exception, I checked by debugging
session.close();
updateStocks();
FacesContext fc = FacesContext.getCurrentInstance();
fc.getELContext().getELResolver().setValue(fc.getELContext(), null, "shoppingCart", null);
//printing Invoice
//writing to file
try {
String content = "Customer Name: " + shoppingcart.getUser().firstName + " " + shoppingcart.getUser().lastName +"\r\n" +
"Address : " + shippingAddress + "\r\n" +
"Date Received: " + shoppingcart.getDate() + "\r\n" +
"Order Items :" + shoppingcart.getOrders() + "\r\n" +
"Money to be received :" + productHolder.subTotal();
// File file = new File("/Users/Vinod/Documents/newfile.txt");
File file = new File("F:/" + shoppingcart.getId() + shoppingcart.getUser().firstName + "invoice.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
System.out.println("Done");
}catch (IOException e) {
e.printStackTrace();
}
return "orderComplete";
}
对我来说,原因很明显:您的 ShoppingCart
实体也是 CDI 托管 bean。我几乎可以肯定你在方法 confirmOrder
:
shoppingcart
@Inject
ShoppingCart shoppingcart;
我说得对吗?如果是,那就是这个原因。
通常 JPA 实体 shouldn't be managed 作为 CDI Beans。这背后的原因是为了防止 BeanManager 执行可能导致 JPA 提供程序中断的操作(因为这导致了您的异常)。
所以请尝试这样的事情:
package domain;
@Entity
public class ShoppingCart implements Serializable {
// ...
}
然后定义另一个 class,它包含上述实体:
package com.some_package;
@Named
@SessionScoped
public class ShoppingCartWrapper {
ShoppingCart store = new ShoppingCart(); // this is your entity
}
这个class可以随便注入。然后保存看起来像:
public String confirmOrder() throws IllegalStateTransitionException {
// ...
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(shoppingCartWrapper.getStore());
session.close();
// ...
}
顺便说一句:个人提示:像这样管理事务 - 我的意思是 "by hand",没有拦截器 容易出错 并且不会使您的代码 干净.