我正在尝试使用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
有什么问题?我只是无法解决这个问题。提前谢谢。
答案 0 :(得分:1)
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>();