调用setter for property - Hibernate Mapping时发生IllegalArgumentException

时间:2015-09-23 07:12:40

标签: java hibernate-mapping

我正在尝试使用Hibernate将集合映射到数据库。  这是我的应用程序类:

package com.shop.hibetnate.application;

import java.util.*;

import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.shop.data.Order;
import com.shop.data.OrderDetails;

public class ManageOrders {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      try{
         factory = new Configuration().configure().buildSessionFactory();
      }catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      ManageOrders MO = new ManageOrders();
      /* Let us have a set of orderDetails for the first order  */
      ArrayList<OrderDetails> set1 = new ArrayList<OrderDetails>();
      set1.add(new OrderDetails(10,10,12,2500));
      set1.add(new OrderDetails(11,11,12,2560));
      set1.add(new OrderDetails(12,12,14,3400));

      /* Add ordder records in the database */
      Integer odID1 = MO.addOrder(10,12,300, set1);

      /* Another set of orderDetails for the second order  */
      ArrayList<OrderDetails> set2 = new ArrayList<OrderDetails>();
      set2.add(new OrderDetails(14,14,13,7500));
      set2.add(new OrderDetails(15,17,12500));

      /* Add another order record in the database */
      Integer odID2 = MO.addOrder(11,15,5000,set2);

      /* List down all the orders */
      MO.listOrders();

      /* Update order's price records */
      MO.updateOrder(odID1, 2900);

      /* Delete an order from the database */
      MO.deleteOrder(odID2);

      /* List down all the orderd */
      MO.listOrders();

   }

   /* Method to add an order record in the database */
   private Integer addOrder(int orderId, int numberOfItems, int totalPrice, ArrayList<OrderDetails> ODetails) {
       Session session = factory.openSession();
          Transaction tx = null;
          Integer orderId1 = null;
          try{
             tx = session.beginTransaction();
             Order order = new Order(orderId, numberOfItems, totalPrice);
             order.setOrderDetails(ODetails);
             orderId1 = (Integer) session.save(order); 
             tx.commit();
          }catch (HibernateException e) {
             if (tx!=null) tx.rollback();
             e.printStackTrace(); 
          }finally {
             session.close(); 
          }
          return orderId1;
}




   /* Method to list all the order detail */
   public void listOrders( ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         List<Order> orders = (List<Order>) session.createQuery("FROM Order"); 
         for (Iterator<Order> iterator1 = 
                           orders.iterator(); iterator1.hasNext();){
            Order order = iterator1.next(); 
            System.out.print("Order Id : " + order.getOrderId()); 
            System.out.print("  Number of Items: " + order.getNumberOfItems()); 
            System.out.println("  Total Price : " + order.getTotalPrice());
            ArrayList<OrderDetails> orderDetails = order.getOrderDetails();
            for (Iterator<OrderDetails> iterator2 = 
                         orderDetails.iterator(); iterator2.hasNext();){
                  OrderDetails orderDetailsId = (OrderDetails) iterator2.next(); 
                  System.out.println("Certificate: " + orderDetailsId.getOrderDetailsId()); 
            }
         }
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to update price for an order */
   public void updateOrder(Integer orderId, int totalPrice ){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Order order = 
                    (Order)session.get(Order.class, orderId); 
         order.setTotalPrice(totalPrice);
         session.update(order);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
   /* Method to delete an order from the records */
   public void deleteOrder(Integer orderId){
      Session session = factory.openSession();
      Transaction tx = null;
      try{
         tx = session.beginTransaction();
         Order order = 
                   (Order)session.get(Order.class, orderId); 
         session.delete(order); 
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      }finally {
         session.close(); 
      }
   }
}

和pojos: Order.java:

package com.shop.data;


import java.util.ArrayList;
import java.util.Date;

import com.shop.data.User;
import com.shop.data.Item;
public class Order {

    private int orderId;
    private Date orderDate;
    private int numberOfItems;
    private int totalPrice;
    User user;
    ArrayList<Item> Items = new ArrayList<Item>();
    ArrayList<OrderDetails> OrderDetails = new ArrayList<OrderDetails>();


    /**
     * @return the orders
     */
    public ArrayList<OrderDetails> getOrderDetails() {
        return OrderDetails;
    }
    /**
     * @param orders the orders to set
     */
    public void setOrderDetails(ArrayList<OrderDetails> orderDetails) {
        OrderDetails = orderDetails;
    }
    /**
     * @return the orderId
     */
    public int getOrderId() {
        return orderId;
    }
    /**
     * @return the orderDate
     */
    public Date getOrderDate() {
        return orderDate;
    }
    /**
     * @return the numberOfItems
     */
    public int getNumberOfItems() {
        return numberOfItems;
    }
    /**
     * @return the totalItems
     */
    public int getTotalPrice() {
        return totalPrice;
    }
    /**
     * @param orderId the orderId to set
     */
    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    /**
     * @param orderDate the orderDate to set
     */
    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }
    /**
     * @param numberOfItems the numberOfItems to set
     */
    public void setNumberOfItems(int numberOfItems) {
        this.numberOfItems = numberOfItems;
    }
    /**
     * @param totalPrice the totalItems to set
     */
    public void setTotalPrice(int totalPrice) {
        this.totalPrice = totalPrice;
    }

    /**
     * @return the user
     */
    public User getUser() {
        return user;
    }
    /**
     * @param user the user to set
     */
    public void setUser(User user) {
        this.user = user;
    }

    /**
     * @return the numberofItems
     */
    /**
     * @return the cart
     */
    public ArrayList<Item> getItems() {
        return Items;
    }
    /**
     * @param cart the cart to set
     */
    public void setItems(ArrayList<Item> items) {
        Items = items;
    }
    public Order(String item, String itemName, double itemPrice,
            String itemSize) {
        // TODO Auto-generated constructor stub
    }
    public Order(int orderId, int numberOfItems, int totalPrice) {
        this.orderId = orderId;
        this.numberOfItems = numberOfItems;
        this.totalPrice = totalPrice;

    }

    public Order() {
        // TODO Auto-generated constructor stub
    }

}

orderDetails.java:

package com.shop.data;

public class OrderDetails {

    private int orderDetailsId;

    Order orderItem = new Order();

    public OrderDetails(int orderDetailsId, int numberofItems, int totalPrice) {
        this.orderDetailsId = orderDetailsId;
        this.orderItem.setNumberOfItems(numberofItems);
        this.orderItem.setTotalPrice(totalPrice);
    }

    public OrderDetails() {
        // TODO Auto-generated constructor stub
    }

    public OrderDetails(int orderid, int orderDetailsId, int numberofItems,
            int totalPrice) {
        this.orderItem.setOrderId(orderid);
        this.orderDetailsId = orderDetailsId;
        this.orderItem.setNumberOfItems(numberofItems);
        this.orderItem.setTotalPrice(totalPrice);
    }

    public int getOrderDetailsId() {
        return orderDetailsId;
    }

    public void setOrderDetailsId(int orderDetailsId) {
        this.orderDetailsId = orderDetailsId;
    }

}

我在调试时遇到以下错误:

ERROR: HHH000091: Expected type: java.util.ArrayList, actual value: org.hibernate.collection.internal.PersistentList
IllegalArgumentException occurred while calling setter for property [com.shop.data.Order.OrderDetails (expected type = java.util.ArrayList)]; target = [com.shop.data.Order@5942ee04], property value = [[com.shop.data.OrderDetails@23cd4ff2, com.shop.data.OrderDetails@70807224, com.shop.data.OrderDetails@7e97551f]]
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:123)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:713)
    at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:362)
    at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4718)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:278)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:138)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
    at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
    at com.shop.hibetnate.application.ManageOrders.addOrder(ManageOrders.java:64)
    at com.shop.hibetnate.application.ManageOrders.main(ManageOrders.java:31)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:68)
    ... 16 more

有什么问题?我只是无法解决这个问题。提前谢谢。

2 个答案:

答案 0 :(得分:1)

TL; DR:编入interface

您的问题在这里:

ArrayList<Item> Items = new ArrayList<Item>();
ArrayList<OrderDetails> OrderDetails = new ArrayList<OrderDetails>();

在这里:

public ArrayList<OrderDetails> getOrderDetails() {
    return OrderDetails;
}
public void setOrderDetails(ArrayList<OrderDetails> orderDetails) {
    OrderDetails = orderDetails;
}

在这里:

public ArrayList<Item> getItems() {
    return Items;
}
public void setItems(ArrayList<Item> items) {
    Items = items;
}

错误清楚地解释了:

  

错误:HHH000091:预期类型:java.util.ArrayList,实际值:org.hibernate.collection.internal.PersistentList

Hibernate从数据库中获取的是 java.util.ArrayList它是org.hibernate.collection.internal.PersistentList - 原因应该是显而易见的。

当您使用Hibernate或许多其他将数据注入bean的框架时,您必须遵守他们的合同。 Hibernate持续List ArrayList

显然ArrayList List所以getter工作正常 - Hibernate并不关心它持久存在的List类型。但是当Hibernate从数据库中读取时,它会创建自己的List实现(它支持延迟填充,脏检查等等)并尝试调用setter - 当它出错时它就在这里。

所以这是另一种情况,即interface的编程不会再回来咬你。

所以你的代码应该是(改为符合Java命名约定,并删除毫无意义的JavaDoc注释):

private List<Item> items;

public List<Item> getItems() {
    return items;
}

public void setItems(List<Item> items) {
    this.items = items;
}

P.S。因为Hibernate将调用setter来替换项目,所以不需要将其实例化为声明 - 这只是浪费。

答案 1 :(得分:0)

你的问题在这里:

public void setOrderDetails(ArrayList<OrderDetails> orderDetails) {
    OrderDetails = orderDetails;
}

将其替换为

public void setOrderDetails(ArrayList<OrderDetails> orderDetails) {
    this.orderDetails = orderDetails;
}

并为属性写

ArrayList<OrderDetails> orderDetails = new ArrayList<OrderDetails>();

评论后

尝试替换

ArrayList<Item> Items = new ArrayList<Item>();
ArrayList<OrderDetails> OrderDetails = new ArrayList<OrderDetails>();

使用

List<Item> Items = new ArrayList<Item>();
List<OrderDetails> OrderDetails = new ArrayList<OrderDetails>();