OpenJPA:持久化SerialBlob时出现异常

时间:2015-12-15 08:39:45

标签: java jpa serialization blob openjpa

我的数据库表有一个包含序列化对象数据的列。相应的JPA实体具有类型为javax.sql.rowset.serial.SerialBlob的字段(实现java.sql.Blob)。

我必须在byte[]SerialBlob之间进行选择。阅读this answer后,我决定使用SerialBlob

该字段名为“notificationData”。我定义了一个额外的便捷方法setNotification(),它采用Notification - 对象,对其进行序列化,然后调用setNotificationData()

使用Hibernate一切正常。但是当使用OpenJPA(生产服务器上的要求)时,在尝试使用通知数据保留新实体时会抛出异常:

Caused by: <openjpa-2.1.2-SNAPSHOT-r422266:1673300 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged object "javax.sql.rowset.serial.SerialBlob@c1d77a2a" in life cycle state  unmanaged while cascading persistence via field "com.mycompany.MyEntity.notificationData" during flush.  However, this field does not allow cascade persist. You cannot flush unmanaged objects or graphs that have persistent associations to unmanaged objects.
 Suggested actions: a) Set the cascade attribute for this field to CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or "persist" or "all" (JPA orm.xml), 
 b) enable cascade-persist globally, 
 c) manually persist the related field value prior to flushing. 
 d) if the reference belongs to another context, allow reference to it by setting StoreContext.setAllowReferenceToSiblingContext().

这是相关的实体代码:

@Lob @Basic
@Column(name = "NOTIFICATION_DATA", nullable = true)
public Blob getNotificationData() {
    return notificationData;
}

public void setNotificationData(Blob notificationData) {
    this.notificationData = notificationData;
}

@Transient
public Notification getNotification() throws SQLException, IOException {
    if (getNotificationData() == null) {
        return null;
    }
    if (notification == null) {
        ObjectInputStream ois = new ObjectInputStream(getNotificationData().getBinaryStream());
        try {
            notification = (Notification) ois.readObject();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Failed de-serializing notification data", e);
        }
        ois.close();
    }
    return notification;
}

public void setNotification(Notification notification) throws SQLException, IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(notification);
    oos.close();
    synchronized (this) {
        this.notification = null;
        this.setNotificationData(new SerialBlob(baos.toByteArray()));
    }
}

我做错了什么?

0 个答案:

没有答案