2017-02-11 18 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 принимает только сериализуемые объекты для значения, а объекты Persistence - сериализуемы. Буду признателен за любую помощь! Следующий код 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 может только (compiletime) проверить, что объект, который является параметром, сериализуется. Однако, если есть связанные объекты, которые не являются сериализуемыми, которые не будут выполняться во время выполнения ... Являются ли Card, Buyer, CartItem (и связанные с ними классы) сериализуемыми? Кроме того, используется ли реализация сериализации List? Начал бы проверять, что ... – tom

+0

Все они сущности Persistence, поэтому они все сериализуемы ... – 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, потому что он имеет метод confirmThisMessage(), ObjectMessage имеет только метод confirm(), который подтверждает все сообщения, и одна часть моей системы зависит от метода confirmThisMessage() потому что мне нужно подтвердить только текущее сообщение. Если есть какая-то альтернатива, я бы с радостью изменил все это на ObjectMessage. Вы знаете о какой-то альтернативе? Какой-то способ признать только последнее полученное сообщение с ObjectMessage? – ZeroCoreCoder

+0

Хм, вы уверены, что данное сообщение не работает на ObjectMessage? Похоже, что вам нужно в любом случае бросить этот метод (сообщение ((com.sun.messaging.jms.Message)) .acknowledgeThisMessage(); '), также следует работать и с ObjectMessage? (По крайней мере _ Интерфейс com.sun.messaging.jms.Message определяет расширенные возможности JMS-сообщения в Sun Java System Message Queue._ из JavaDoc предполагает, что) – tom

+0

Большое вам спасибо, я начал изменять систему и вскоре Я узнаю результат, но все выглядит хорошо! – ZeroCoreCoder