Using AttributeConverter

0
3099

AttributeConverter introduced in JPA 2.1. This article demonstrates JPA/Hibernate AttributeConverter with an example.

What is JPA AttributeConverter? AttributeConverter is an interface, a class that implements AttributeConverter interface can be used to convert entity attribute state into database column representation and back again.  In other words AttributeConverter can be used to map Java type to JDBC type to an entity.

Following image illustrates the mapping between a Name custom Java type to VARCHAR type in database.

JPA AttributeConverter Example

1. How to use AttributeConverter?

1.1. AttributeConverter has following methods and the class which implements this interface should provide implementation for the methods.

  1. Y convertToDatabaseColumn(X attribute) – Converts the value stored in the entity attribute into the data representation to be stored in the database.
  2. X convertToEntityAttribute(Y dbData) – Converts the data stored in the database column into the value to be stored in the entity attribute.

1.2. Following are the steps to use AttributeConverter.

  1. Create a class that should implement AttributeConverter interface.
  2. Use @Convert annotation to use the class created in step 1.

Following example demonstrates the how to use AttributeConverter.

2. JPA AttributeConverter Example

2.1. Following is the Name java class to represent User full name. name = first name + last name.

public class Name {
	
	private String fisrtName;
	
	private String lastName;
	

	// setters and getters
}

2.2. Creating Attribute converter for the Name java type. Following class shows you how to create Attribute converter class.

@Converter(autoApply = true)
public class NameAttributeConveter implements AttributeConverter<Name, String>{

	@Override
	public String convertToDatabaseColumn(Name attribute) {
		
		String fname = attribute.getFisrtName() == null ? "anonymous" : attribute.getFisrtName();
		String lname = attribute.getLastName() == null ? "" : attribute.getLastName();
		
		return  fname+" "+lname;
	}

	@Override
	public Name convertToEntityAttribute(String dbData) {
		
		if(dbData!=null && dbData.split(" ").length > 0) {
			Name name = new Name();
			name.setFisrtName(dbData.split(" ")[0]);
			name.setLastName(dbData.split(" ")[1]);
			
			return name;
		}
			
		return null;
	}
}

2.3. Using NameAttributeConveter to map Name field in User entity.

@Entity(name = "USER")
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
	@GenericGenerator(name = "native", strategy = "native")
	@Column(name = "ID")
	private Long id;

	@Column(name = "USER_NAME")
	private String userName;

	@Column(name = "PASSWORD")
	private String password;
	
	@Convert(converter = NameAttributeConveter.class)
	@Column
	private Name name;

        // Other fields mapping and setters getters
}

2.4. While implementing if you set autoApply = true to the annotation @Converter, you no need to use @Convert annotation explicitly on the attributes. The default value for autoApply is false.

2.5. Testing the mapping. Following code is to test the mapping.

public class App 
{
    public static void main( String[] args )
    {
    	EntityManagerFactory emf = null;
		EntityManager entityManager = null;
		EntityTransaction transaction = null;
		
		try{
			emf = Persistence.createEntityManagerFactory("jbd-pu");
			entityManager = emf.createEntityManager();
			transaction = entityManager.getTransaction();
			transaction.begin();
			
			User user = new User();
			user.setUserName("mike");
			user.setPassword("password");
			
			Name name = new Name();
			name.setFisrtName("Mike");
			name.setLastName("Chan");
			user.setName(name);
			
			// Setting Current Date
			user.setCreationTime(new Date());
			user.setDateofBirth(new Date());
			user.setUserType(UserType.EMPLOYEE);
	
			entityManager.persist(user);
			transaction.commit();
		}catch(Exception e){
			transaction.rollback();
			e.printStackTrace();
		}finally{
			entityManager.close();
			emf.close();
		}
    }
}

2.6. Database Results

AttributeConverter Example database results

3. Conclusion

In this article we have covered Jpa 2.1 AttributeConverter with an example.

References

  1. JPA Document
  2. Hibernate Document
  3. JPA and Hibernate Enum mapping

LEAVE A REPLY

Please enter your comment!
Please enter your name here