3

I've read the discussion between @transient and transient keyword: Why does JPA have a @Transient annotation?

But when I make certain field transient using the java keyword and NOT the @Transient notation, those fields are not created in my table on table creation. Why is this?

Here is my persistence.xml :

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="someDB" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>somewhere.classnameA</class>
        <class>somewhere.classnameB</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url"
                value="jdbc:mysql://localhost:3306/project" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="" />

            <!-- EclipseLink should create the database schema automatically -->
            <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
            <property name="eclipselink.ddl-generation.output-mode"
                value="both" />
        </properties>

here is an example entity:

import java.sql.Timestamp;

import com.google.gwt.user.client.rpc.IsSerializable;

@Entity
public class Session implements IsSerializable{

    @Id
    @Basic(optional = false)
    @Column(length = 36)
    private String sessionID;

    @Version
    @Basic(optional = false)
    transient private Timestamp lastModification;

    @Basic(optional = false)
    transient private Timestamp expireTime;

    @OneToOne(optional = false)
    private User user;

    protected Session(){

    }

    // constructor server side
    public Session(String sessionID, User user, Timestamp expireTime){
        this.sessionID = sessionID;
        this.user = user;
        this.expireTime = expireTime;
    }

    public String getSessionID() {
        return sessionID;
    }

    public void setSessionID(String sessionID) {
        this.sessionID = sessionID;
    }

    public Timestamp getLastModification() {
        return lastModification;
    }

    public void setLastModification(Timestamp lastModification) {
        this.lastModification = lastModification;
    }

    public Timestamp getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(Timestamp expireTime) {
        this.expireTime = expireTime;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    @Transient
    public String toString() {
        String userID = (user != null) ? String.valueOf(user.getUserID()) : "?";
        return String.format("(%s)%s", userID, sessionID);
    }


}

Note: In the above file, I removed some unimportant imports. In the generated table there are only two fields namely SESSIONID and USER_USERID. I also used the persistence api 1.0

Community
  • 1
  • 1
Vjeetje
  • 5,314
  • 5
  • 35
  • 57

3 Answers3

6

From the JPA point of view the annotation and the modifier are perfectly equivalent and both mean that the field is not persisted. See paragraph 2.1.1 of the JSR 220 Specification where it says:

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 the Transient annotation are persistent.
Elnur Abdurrakhimov
  • 44,533
  • 10
  • 148
  • 133
remigio
  • 4,101
  • 1
  • 26
  • 28
  • 1
    In that case, is there any other way to specify that certain fields should be stored in the database, but not be send over the wire? I'm looking for an alternative to making a DTO. – Vjeetje Jan 08 '13 at 15:20
  • Annotate the property access methods instead. But mapping transient fields will cause problems should you merge in a serialized object - the value in the database may end up being overwritten with null. – Chris Jan 08 '13 at 15:59
  • @GWT4Ever It depends on how you would send entities to clients. In case of exposing a web service interface using JAX-WS you could annotate them with `@XmlRootElement` and mark fields you don't want to be transmitted with `@XmlTransient`. – remigio Jan 08 '13 at 16:29
  • @Chris This is the reason why the `transient` modifier is equivalent to the `@Transient` annotation, both ways the field is not mapped to any database column. – remigio Jan 08 '13 at 16:31
0

Transient fields are do not participate in persistence and their values are never stored in the database similar to transient fields in Java that do not participate in serialization

Thadeuse
  • 1,713
  • 2
  • 12
  • 19
0

ANSWER from book - Pro JPA Mastering the JPA

.. We have used the transient modifier instead of the @Transient annotation so that if the Employee(e.g. an entity) gets serialized from one VM to another then the field will get reinitialized to correspond to the locale of the new VM. In cases where the non-persistent value should be retained across serialization, the annotation should be used instead of the modifier.

Azat
  • 1