In this post, I’d like to explain why and when to use the @Transient annotation in Java application development with the Java/Jakarta Persistence API (JPA) and Hibernate framework.

In short, we use the @Transient annotation in an entity class for a field or property that is not persistent. In other words, when a field or property is marked as @Transient, Hibernate won’t map it to any column in the underlying database. This annotation can also be used for getters in an entity class.

And as per its Javadocs, it is used to annotate a property or a field in an entity class, mapped superclass, or embeddable class.

Let me explain with a couple of real-world examples.

 

1. Using @Transient for Getter (Method-level)

Given the following entity class that maps to the users table in the database:

package net.codejava;

import jakarta.persistence.*;

@Entity
@Table(name = "users")
public class User {
	@Column(length = 128, nullable = false, unique = true)
	private String email;
	
	@Column(length = 64, nullable = false)
	private String password;
	
	@Column(name = "first_name", length = 45, nullable = false)
	private String firstName;
	
	@Column(name = "last_name", length = 45, nullable = false)
	private String lastName;
	
	// getters and setters...
}
In this entity class, note that the field firstName maps to the column first_name, and the field lastName maps to the column last_name in the database. In other words, values of these fields are persistent.

And in the view layer, e.g., users.html we want to display users’ full names like this:

<table>	
	<tr th:each="user : ${listUsers}">

		...
		<td>[[${user.fullName}]]</td>
		...		
	</tr>	
</table>
This will invoke the getFullName() getter in the User class, which is implemented as follows:

@Transient
public String getFullName() {
	return firstName + " " + lastName;
}


Here, we need mark the getter with @Transient annotation to tell Hibernate that it doesn’t map to any column in the database. Otherwise, Hibernate will infer that this method is for the persistent property named fullName and throw the error: Unknown column ‘full_name’ in ‘field list’.

Of course, we don’t need to persist users’ full name because the full name is just combination of first name and last name, which are marked as persistent using the @Column annotation, as seen above.

In this example, you can see the @Transient annotation is used at method level.

 

The following video demonstrates the use of this annotation in a real-world projetct. Check it out:

 

2. Using @Transient for Property (Field-level)

Let’s look at another example that explains the use of @Transient annotation. Given the following entity class:

package net.codejava;

import jakarta.persistence.*;

@Entity
@Table(name = "client_apps")
public class ClientApp {

	...
	
	@Column(nullable = false, length = 100, unique = true)
	private String clientId;
	
	@Column(nullable = false, length = 100, unique = true)
	private String encodedClientSecret;
	
	// getters and setters
}
In the view layer, we want to display the raw value of the client secret to the users once, like this:

[[${clientApp.rawClientSecret}]]
Only the encoded value of client secret is persisted (better security) whereas the raw value (not encoded) is shown to the users once. Therefore, we need to add a transient field with a getter and setter to the entity class, as shown in the following code:

@Entity
@Table(name = "client_apps")
public class ClientApp {

	...

	@Transient
	private String rawClientSecret;

	public String getRawClientSecret() {
		return this.rawClientSecret;
	}

	public void setRawClientSecret(String rawClientSecret) {
		this.rawClientSecret = rawClientSecret;
	}
	
}
This ensures that Hibernate won’t map the field rawClientSecret to a column in the database. In other words, the value of this field is transient - it won’t be persisted. Otherwise, Hibernate will throw the error: Unknown column ‘raw_client_secret’ in ‘field list’ at runtime.

That’s the purpose of using the @Transient annotation. Make sense now?

 

Conclusion

When we must add a field, property or getter to an entity class, but the value is not persisted in database, we must use the @Transient annotation. This is because, by default, the Hibernate ORM framework considers fields and getters in entity classes to be mapped to columns in a database table. So, if we don’t use the @Transient annotation, it will throw an “unknown column in field list error”. You can use this annotation for a field, property or getter in an entity class.

 

Hibernate and JPA Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment