2017-02-11 100 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