I want to avoid serialisation ( in JMS / AMF ) but still persist the field with JPA/Hibernate.
Is the transient
modifier my friend ? Are @Transient
annotation and the transient
modifier related or not a all ?
The java specification precise that a transient field will not be saved to a persistent storage by a system service. But is hibernate a system service ? ( i dont think so ) http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#78119
And java.io.Serialisable
seams to indicate that a out.writeObject
and in.readObject
are called for serialisation
http://download.oracle.com/javase/1.4.2/docs/api/java/io/Serializable.html
Any insight ?
Maybe should i just write a quick test, but i will be more confident with a piece of spec.
Thank !
Java's transient keyword is used to denote that a field is not to be serialized, whereas JPA's @Transient annotation is used to indicate that a field is not to be persisted in the database, i.e. their semantics are different.
@Transient annotation is used to ignore a field to not persist in database in JPA, where as transient key word used to ignore a field from serialization. The field annotated with @Transient still can be serialized, but the field declared with transient keyword not to be persisted and not to be serialized.
@Transient Annotation vs. The transient keyword is primarily meant for ignoring fields during Java object serialization, but it also prevents these fields from being persisted when using a JPA framework. In other words, the transient keyword has the same effect as the @Transient annotation when saving to a database.
You use hibernate as implementation of JPA API. You should be able to change hibernate with another implementation (like EclipseLink) without changing in the code. This is why you should only use JPA annotations.
Is the
transient
modifier my friend ? Are@Transient
annotation and thetransient
modifier related or not a all ?
They are not really related but I'm afraid they won't be your friend anyway, transient
properties aren't persisted by Hibernate/JPA. The JPA specification puts it like this:
2.1.1 Persistent Fields and Properties
The persistent state of an entity is accessed by the persistence provider runtime either via JavaBeans style property accessors or via instance variables. A single access type (field or property access) applies to an entity hierarchy. When annotations are used, the placement of the mapping annotations on either the persistent fields or persistent properties of the entity class specifies the access type as being either field - or property - based access respectively.
- If the entity has field-based access, the persistence provider runtime accesses instance variables directly. All non-
transient
instance variables that are not annotated with theTransient
annotation are persistent. When field-based access is used, the object/relational mapping annotations for the entity class annotate the instance variables.- If the entity has property-based access, the persistence provider runtime accesses persistent state via the property accessor methods. All properties not annotated with the
Transient
annotation are persistent. The property accessor methods must be public or protected. When property-based access is used, the object/relational mapping annotations for the entity class annotate the getter property accessors.- Mapping annotations cannot be applied to fields or properties that are
transient
orTransient
.- The behavior is unspecified if mapping annotations are applied to both persistent fields and properties or if the XML descriptor specifies use of different access types within a class hierarchy.
...
The part of JPA specification posted by Pascal Thivent looks rather confusing. Actually, Hibernate respects transient
when field access is used, but ignores in the case of property access. Perhaps it's a Hibernate-specifc behaviour.
For example, in this case bar
is not serialized, but still persisted to the database:
@Entity
@Access(AccessType.FIELD) // Default access type - field
public class Foo {
@Id @GeneratedValue
private Long id;
transient private String bar;
...
@Access(AccessType.PROPERTY) // Override default access type for this property
public String getBar() { return bar; }
}
EDIT: Since it's unclear how this behaviour conforms to the JPA Specification, perhaps the better choice is to use different names for the transient
field and the corresponding property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With