请教一个问题,在练习EJB3.0 双向关联时出现了一下错误。使用平台是JBOSS5.0+ myEclipse6.5 
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at $Proxy2.getOrderByID(Unknown Source)
at com.ejb.OneToMany.Test.Test.main(Test.java:40)
Caused by: org.jboss.remoting.InvocationFailureException: Unable to perform invocation; nested exception is: 
java.io.InvalidClassException: org.hibernate.collection.AbstractPersistentCollection; local class incompatible: stream classdesc serialVersionUID = -5723701046347946317, local class serialVersionUID = -7982170513654570219
at org.jboss.remoting.transport.socket.SocketClientInvoker.handleException(SocketClientInvoker.java:139)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:886)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:160)
at org.jboss.remoting.Client.invoke(Client.java:1708)
at org.jboss.remoting.Client.invoke(Client.java:612)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy3.invoke(Unknown Source)
at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
at org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
... 2 more
Caused by: java.io.InvalidClassException: org.hibernate.collection.AbstractPersistentCollection; local class incompatible: stream classdesc serialVersionUID = -5723701046347946317, local class serialVersionUID = -7982170513654570219
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at org.jboss.aop.joinpoint.InvocationResponse.readExternal(InvocationResponse.java:119)
at java.io.ObjectInputStream.readExternalData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.receiveObjectVersion2_2(JavaSerializationManager.java:238)
at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.receiveObject(JavaSerializationManager.java:138)
at org.jboss.remoting.marshal.serializable.SerializableUnMarshaller.read(SerializableUnMarshaller.java:123)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.versionedRead(MicroSocketClientInvoker.java:1215)
at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:845)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:160)
at org.jboss.remoting.Client.invoke(Client.java:1708)
at org.jboss.remoting.Client.invoke(Client.java:612)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy3.invoke(Unknown Source)
at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
at org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
at $Proxy2.getOrderByID(Unknown Source)
at com.ejb.OneToMany.Test.Test.main(Test.java:40)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:72)
... 13 more
共两个EntityBean:
   order oredrItem.数据可以增加,但是查询就出错

解决方案 »

  1.   

    package com.ejb.OneToMany.EntityBean;
    import java.io.Serializable;
    import java.util.HashSet;
    import java.util.Date;
    import java.util.Set;import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.OrderBy;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;@Entity
    @Table(name = "Orders")
    public class Order implements Serializable { private static final long serialVersionUID = 4970325922198249712L;
    private Integer orderid;
        private Float amount;
        private Set<OrderItem> orderItems = new HashSet<OrderItem>();
        private Date createdate;    @Id
        @GeneratedValue  
        public Integer getOrderid() {
            return orderid;
        }
        public void setOrderid(Integer orderid) {
            this.orderid = orderid;
        }
        
        public Float getAmount() {
            return amount;
        }    
        public void setAmount(Float amount) {
            this.amount = amount;
        }
        
        @OneToMany(mappedBy="order",cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        @OrderBy(value = "id ASC")
        public Set<OrderItem> getOrderItems() {
            return orderItems;
        }
        public void setOrderItems(Set<OrderItem> orderItems) {
            this.orderItems = orderItems;
        }
        
        @Temporal(value=TemporalType.TIMESTAMP)
        public Date getCreatedate() {
            return createdate;
        }
        public void setCreatedate(Date createdate) {
            this.createdate = createdate;
        }
        
        public void addOrderItem(OrderItem orderitem) {
         System.out.println("helllo");
           if (!this.orderItems.contains(orderitem)) {
                this.orderItems.add(orderitem);
                orderitem.setOrder(this);
           }
        }    public void removeOrderItem(OrderItem orderitem) {
            if (this.orderItems.contains(orderitem)) {
                orderitem.setOrder(null);
                this.orderItems.remove(orderitem);
            }
        }
        
        /**
         * 返回对象的散列代码值。该实现根据此对象
         * 中 orderid 字段计算散列代码值。
         * @return 此对象的散列代码值。
         */
        @Override
        public int hashCode() {
            int hash = 0;
            hash += (this.orderid != null ? this.orderid.hashCode() : 0);
            return hash;
        }    /**
         * 确定其他对象是否等于此 Order。当且仅当
         * 参数不为 null 且该参数是具有与此对象相同 orderid 字段值的 Order 对象时,
         * 结果才为 <code>true</code>。
         * @param 对象,要比较的引用对象
         * 如果此对象与参数相同,则 @return <code>true</code>;
         * 否则为 <code>false</code>。
         */
        @Override
        public boolean equals(Object object) {
            if (!(object instanceof Order)) {
                return false;
            }
            Order other = (Order)object;
            if (this.orderid != other.orderid && (this.orderid == null || !this.orderid.equals(other.orderid))) return false;
            return true;
        }    /**
         * 返回对象的字符串表示法。该实现根据 orderid 字段
         * 构造此表示法。
         * @return 对象的字符串表示法。
         */
        @Override
        public String toString() {
            return this.getClass().getName()+ "[orderid=" + orderid + "]";
        }
    }
      

  2.   

    package com.ejb.OneToMany.EntityBean;import java.io.Serializable;import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;@Entity
    public class OrderItem implements Serializable { private static final long serialVersionUID = -1166337687856636179L;
    private Integer id;
        private String productname;
        private Float price;
        private Order order;
        
        public OrderItem() {}
     
        public OrderItem(String productname, Float price) {
            this.productname = productname;
            this.price = price;
        }    @Id
        @GeneratedValue 
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        } 
        
        @Column(length=100, nullable=false)
        public String getProductname() {
            return productname;
        }
        public void setProductname(String productname) {
            this.productname = productname;
        }
        
        public Float getPrice() {
            return price;
        }
        public void setPrice(Float price) {
            this.price = price;
        }
        
        @ManyToOne(cascade=CascadeType.REFRESH, optional=false)
        @JoinColumn(name = "order_id")  
        public Order getOrder() {
            return order;
        }
        public void setOrder(Order order) {
            this.order = order;
        }
        
        /**
         * 返回对象的散列代码值。该实现根据此对象
         * 中 id 字段计算散列代码值。
         * @return 此对象的散列代码值。
         */
        @Override
        public int hashCode() {
            int hash = 0;
            hash += (this.id != null ? this.id.hashCode() : super.hashCode());
            return hash;
        }    /**
         * 确定其他对象是否等于此 OrderItem。当且仅当
         * 参数不为 null 且该参数是具有与此对象相同 id 字段值的 OrderItem 对象时,
         * 结果才为 <code>true</code>。
         * @param 对象,要比较的引用对象
         * 如果此对象与参数相同,则 @return <code>true</code>;
         * 否则为 <code>false</code>。
         */
        @Override
        public boolean equals(Object object) {
            if (!(object instanceof OrderItem)) {
                return false;
            }
            OrderItem other = (OrderItem)object;
            if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) return false;
            return true;
        }    /**
         * 返回对象的字符串表示法。该实现根据 id 字段
         * 构造此表示法。
         * @return 对象的字符串表示法。
         */
        @Override
        public String toString() {
            return this.getClass().getName()+ "[id=" + id + "]";
        }
    }
      

  3.   

    package com.ejb.OneToMany.impl;import java.util.List;import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;import com.ejb.OneToMany.EntityBean.*;
    import com.ejb.OneToMany.Remote.*;@Stateless
    @Remote (OrderDAO.class)
    public class OrderDAOBean implements OrderDAO {
        @PersistenceContext protected EntityManager em;
        
        public void insertOrder(Order order){
            em.persist(order);
        }    public Order getOrderByID(Integer orderid) {
           Order order =  em.find(Order.class, orderid);
           order.getOrderItems().size();
           //因为是延迟加载,通过执行size()这种方式获取订单下的所有订单项
           return order;
        }    @SuppressWarnings("unchecked")
    public List<Order> getAllOrder() {
            Query query = em.createQuery("select DISTINCT o from Order o inner join fetch o.orderItems order by o.orderid");
            return (List<Order>) query.getResultList();
        }
    }
      

  4.   

    serialVersionUID = -5723701046347946317和serialVersionUID = -7982170513654570219是哪个类的serialVersionUID?把这个类找到。Order和OrderItem基本上没问题。只是在
    private Set <OrderItem> orderItems = new HashSet <OrderItem>();
    这行,后面的赋值是没有必要的,写成
    private Set<OrderItem> orderItems;
    就可以了。
      

  5.   

    serialVersionUID = -5723701046347946317和serialVersionUID = -7982170513654570219是哪个类的serialVersionUID?把这个类找到。 是实体类中的一个句子。
      

  6.   

    private Set<OrderItem> orderItems;不行。这是一个空对象哦
      

  7.   

    我知道是实体类,问题是哪个实体类,Order和OrderItem的serialVersionUID分别是4970325922198249712L,-1166337687856636179L。跟错误信息中的不一致。也就是说导致问题的不是Order和OrderItem这两个类。实体类的实例化分为两种情况,一种是向数据库中添加新实体时,使用new关键字创建新实例,另一种是调用EntityManager的find方法,或者Query的getResultList和getSingleResult方法,有持久化提供者创建并填充数据。在后一种情况下,你在声明字段是所赋的初始值就完全是多余的,并且会损害应用程序的性能。并且一般来说,后一种情况比前一种情况要普遍得多。所以较好的做法是,当你需要为一个new Order添加OrderItem时,先调用一下它的setOrderItems方法:
    Order order = new Order();
    order.setOrderItems(new HashSet<OrderItem>());
    OrderItem item = ...;
    order.getOrderItems.add(item);
    ...
      

  8.   

    问题已解决。是少加了一个包。herbinate_core.jar
    谢谢大家关注,都给分。O(∩_∩)O哈哈~
    都交流