Sleep mode attempts to serialize the field marked by @Transient

I am trying to save a collection of what I would call relatively simple objects in a database. Unfortunately, Hibernate seems to be ignoring the @Transient annotation (or trying to serialize, even with annotation) on several of my classes. This causes an unpleasant error when I have classes that cannot be serialized.

If necessary, I can make the AxisEventHandler class serializable, however, if I couldn’t (for example, this was the last class in a closed source library), what would I do then?

I can provide additional information about the GenericEventHandler class or any of the code I commented for brevity on request (but I don't think they are especially important ... I could be wrong).

An exception:

org.hibernate.type.SerializationException: could not serialize at org.hibernate.util.SerializationHelper.serialize(SerializationHelper.java:139) at org.hibernate.util.SerializationHelper.serialize(SerializationHelper.java:164) at org.hibernate.util.SerializationHelper.clone(SerializationHelper.java:95) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor$SerializableMutabilityPlan.deepCopyNotNull(SerializableTypeDescriptor.java:54) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor$SerializableMutabilityPlan.deepCopyNotNull(SerializableTypeDescriptor.java:42) at org.hibernate.type.descriptor.java.MutableMutabilityPlan.deepCopy(MutableMutabilityPlan.java:58) at org.hibernate.type.AbstractStandardBasicType.deepCopy(AbstractStandardBasicType.java:314) at org.hibernate.type.AbstractStandardBasicType.deepCopy(AbstractStandardBasicType.java:310) at org.hibernate.type.TypeHelper.deepCopy(TypeHelper.java:68) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:302) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697) at com.mypandafinance.amino.gui.ccsimple.CCSimpleApp.initApplication(CCSimpleApp.java:55) at com.mypandafinance.amino.AminoBoot.main(AminoBoot.java:101) Caused by: java.io.NotSerializableException: com.mypandafinance.chartcomponent.eventhandlers.AxisEventHandler at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346) at org.hibernate.util.SerializationHelper.serialize(SerializationHelper.java:135) ... 21 more 

Main axis class:

 @Entity @Inheritance(strategy=InheritanceType.JOINED) public abstract class Axis implements Serializable { private int axisId; @Id @GeneratedValue(strategy = GenerationType.AUTO) public int getAxisId() { return axisId; } protected void setAxisId(int id) { this.axisId = id; } @Transient public abstract long getMax(); public abstract void setMax(long max); @Transient public abstract long getMin(); public abstract void setMin(long min); /* ... helper methods here */ @Transient public abstract AxisEventHandler getEventHandler(); @Transient public abstract AxisFlagHandler getFlagHandler(); @Transient public abstract TickMarkFormatter getTickMarkFormatter(); public abstract void setTickMarkFormatter(TickMarkFormatter formatter); } 

The main implementation:

 @Entity @SecondaryTable(name="BasicAxis") public class BasicAxis extends Axis { private long min; private long max; // Event handler, used for firing off events to all listeners private AxisEventHandler eventHandler = new AxisEventHandler(); // Flag handler, used for storing axis flags private SerializableAxisFlagHandler flagHandler; private TickMarkFormatter formatter; /* ... constructors */ @Column(name="rangemax") @Override public long getMax() { return max; } @Override public void setMax(long max) { /* ... */ } @Column(name="rangemin") @Override public long getMin() { return min; } @Override public void setMin(long min) { /* ... */ } @Override public void setRange(long min, long max) { /* ... */ } @Override public void pan(long amount) { /* ... */ } @Transient @Override public AxisEventHandler getEventHandler() { /* ... */ } @Type(type="com.mypandafinance.chartcomponent.hibernateusertypes.AxisFlagHandlerUserType") @Column(name="flags") @Override public SerializableAxisFlagHandler getFlagHandler() { /* ... */ } protected void setFlagHandler(SerializableAxisFlagHandler flagHandler) { /* ... */ } @Column(name="formatter", table="BasicAxis") @Override public TickMarkFormatter getTickMarkFormatter() { /* ... */ } @Override public void setTickMarkFormatter(TickMarkFormatter formatter) { /* ... */ } /* ... helper methods */ } 

AxisEventHandler Class:

 public class AxisEventHandler extends GenericEventHandler<AxisEventListener> { public AxisEventHandler() { super(new AxisEventListener[0]); } } 
+4
source share
2 answers

Nothing, I seem to be mistaken that, looking back, I did not need to take several hours to understand. The problem was not in sleep mode, but in Hibernate (except that Hibernate used standard Java serialization).

Field values ​​need not be marked with a JPA @Transient annotation, but they must also be temporary for the Serializable interface (because for some reason does Hibernate serialize objects before saving them?)

Fix:

 public class BasicAxis extends Axis { /* ... */ private transient AxisEventHandler eventHandler = new AxisEventHandler(); /* ... */ } 
+4
source

This happened to me, and I also lost a watch. Adding a transient Java modifier that got rid of an immediate error, I continued to get more and more strange serialization errors until the final Hibernate complained that it could not shorten the binary representation of my object in the field (because it is too long: / p>

 Caused by: org.h2.jdbc.JdbcBatchUpdateException: Value too long for column 

The real problem? I accidentally ruined the JPA annotation. I have done this:

 @Column(name = "val_foo") private Foo val; 

Instead of this:

 @OneToOne(targetEntity = FooImpl.class, cascade = { PERSIST }) @JoinColumn(name = "val_foo", referencedColumnName = "uuid") private Foo val; 

Hope this ever helps someone ...

+1
source

Source: https://habr.com/ru/post/1385476/


All Articles