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",没有拦截器 容易出错 并且不会使您的代码 干净.