2017-02-11 101 views
1

我收到以下错误:持久性实体不能序列

SEVERE: null 
javax.jms.MessageFormatException: [C4017]: Invalid message format. 
at com.sun.messaging.jmq.jmsclient.MapMessageImpl.checkValidObjectType(MapMessageImpl.java:653) 
at com.sun.messaging.jmq.jmsclient.MapMessageImpl.setObject(MapMessageImpl.java:632) 
at buyer.Main.sendCart(Main.java:287) 

后,我尝试通过在MapMessage消息JMS系统发送持久性对象。我不太确定为什么会发生这种情况,因为MapMessage仅接受可序列化的对象以获取值,而持久性实体是可序列化的。我将不胜感激任何帮助!我的Java代码如下。

package entities; 

import java.io.Serializable; 
import java.util.List; 
import java.util.Objects; 
import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.ManyToOne; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.PrimaryKeyJoinColumn; 
import javax.persistence.Table; 

@Entity 
@Table(name = "carts") 
@NamedQuery(
    name = "carts.findAll", 
    query = "select c from Cart c" 
) 
public class Cart implements Serializable { 

private static final long serialVersionUID = 1L; 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "id") 
private Long id; 

@Column(name = "buyer_id") 
private Long buyerId; 

@Column(name = "card_id") 
private Long cardId; 

@Column(name = "successful") 
private boolean successful; 

@ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER) 
@PrimaryKeyJoinColumn(name = "buyer_id") 
private Buyer buyer; 

@ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER) 
@PrimaryKeyJoinColumn(name = "card_id") 
private Card card; 

@OneToMany(mappedBy = "cart", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER) 
private List<CartItem> cartItems; 

public Cart() { 
} 

public Cart(Long buyerId, Long cardId, boolean successful) { 
    this.buyerId = buyerId; 
    this.cardId = cardId; 
    this.successful = successful; 
} 

public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 

public Long getBuyerId() { 
    return buyerId; 
} 

public void setBuyerId(Long buyerId) { 
    this.buyerId = buyerId; 
} 

public Long getCardId() { 
    return cardId; 
} 

public void setCardId(Long cardId) { 
    this.cardId = cardId; 
} 

public boolean isSuccessful() { 
    return successful; 
} 

public void setSuccessful(boolean successful) { 
    this.successful = successful; 
} 

public Buyer getBuyer() { 
    return buyer; 
} 

public void setBuyer(Buyer buyer) { 
    this.buyer = buyer; 
} 

public Card getCard() { 
    return card; 
} 

public void setCard(Card card) { 
    this.card = card; 
} 

public List<CartItem> getCartItems() { 
    return cartItems; 
} 

public void setCartItems(List<CartItem> cartItems) { 
    this.cartItems = cartItems; 
} 

@Override 
public int hashCode() { 
    int hash = 7; 
    hash = 53 * hash + Objects.hashCode(this.id); 
    hash = 53 * hash + Objects.hashCode(this.buyerId); 
    hash = 53 * hash + Objects.hashCode(this.cardId); 
    hash = 53 * hash + (this.successful ? 1 : 0); 
    return hash; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) { 
     return true; 
    } 
    if (obj == null) { 
     return false; 
    } 
    if (getClass() != obj.getClass()) { 
     return false; 
    } 
    final Cart other = (Cart) obj; 
    if (this.successful != other.successful) { 
     return false; 
    } 
    if (!Objects.equals(this.id, other.id)) { 
     return false; 
    } 
    if (!Objects.equals(this.buyerId, other.buyerId)) { 
     return false; 
    } 
    if (!Objects.equals(this.cardId, other.cardId)) { 
     return false; 
    } 
    return true; 
} 

@Override 
public String toString() { 
    return "Cart{" + "id=" + id + ", buyerId=" + buyerId + ", cardId=" + cardId + ", successful=" + successful + '}'; 
} 
} 

发送消息的相关方法。

private static Buyer sendCart(Cart cart, String tempId, Buyer buyer) { 
    JMSContext context = connectionFactory.createContext(2); 

    try { 
     Destination queue = context.createQueue("mediator"); 
     JMSProducer producer = context.createProducer(); 

     MapMessage message = context.createMapMessage(); 

     message.setObject("data", cart); 
     message.setObject("tempid", tempId); 
     message.setObject("type", MessageType.BUYER_SENDING_CART); 

     producer.send(queue, message); 

    } catch (JMSException ex) { 
     Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
+0

我只想提的是错误的'message.setObject(“数据”,购物车)发生;'线。 – ZeroCoreCoder

+0

MapMessage只能(编译时)检查,该参数的对象是可序列化的。但是,如果有相关的对象不可序列化,将在运行时失败...... Card,Buyer,CartItem(及其相关类)是否可序列化为?另外,List可用的实现是否可序列化?将开始检查... – tom

+0

他们都是持久性实体,所以他们都是可序列化的... – ZeroCoreCoder

回答

0

问题是MapMessage。据JavaDoc

A MapMessage object is used to send a set of name-value pairs. The names are String objects, and the values are primitive data types in the Java programming language. The names must have a value that is not null, and not an empty string. The entries can be accessed sequentially or randomly by name. The order of the entries is undefined. MapMessage inherits from the Message interface and adds a message body that contains a Map.

和:

They may also be read or written generically as objects.

所以,即使提供MapMessage消息的 “的setObject” 方法,使用的必须是原始类型的参数。

要通过非原始类型使用ObjectMessage

+0

我需要使用MapMessage,因为它有acknowledgeThisMessage()方法,ObjectMessage只有确认所有消息的确认()方法,我的系统的一部分依赖于acknowledgeThisMessage()方法因为我只需要确认当前的消息。如果还有其他选择,我会很乐意将其全部更改为ObjectMessage。你知道一些替代品吗?用ObjectMessage只确认最后收到的消息的一些方法? – ZeroCoreCoder

+0

嗯,你确定acknowledgeThisMessage不能在ObjectMessage上工作吗?似乎你必须施展才能获得该方法('((com.sun.messaging.jms.Message)message).acknowledgeThisMessage();'),也应该在ObjectMessage上工作? (至少_The com.sun.messaging.jms.Message接口定义了Sun Java System Message Queue._中来自JavaDoc的JMS消息的增强功能) – tom

+0

非常感谢,我已经开始修改系统,并很快我会知道结果,但现在看起来都很好! – ZeroCoreCoder