DeltaSpike is now providing a Data module allowing to use interface or abstract classes as repositories for JPA (a bit like spring-data). It got recently a new feature aiming to support DTOs pattern.
I’ll just show how to use it on a simple “User” entity in this post.
First I suppose you set up correctly your JPA project and you have a User entity like this one:
// imports @Entity public class User { @Id @GeneratedValue private long id; private String name; public long getId() { return id; } public String getName() { return name; } public void setName(final String name) { this.name = name; } }
Of course in this “hello world” the “UserDto” will be really close of it:
public class UserDto { private long id; private String name; public long getId() { return id; } public void setId(final long id) { this.id = id; } public String getName() { return name; } public void setName(final String name) { this.name = name; } }
To create a repository for User we just need the following class by default:
@Repository public interface MyRepository extends EntityRepository<User, Long> { }
However i recommand you to explicity resolve the persistence unit you want if you are in a modular application. To do so just implement org.apache.deltaspike.data.api.EntityManagerResolver and return your EntityManager. In JavaEE it looks like:
@ApplicationScoped public class MyUnitResolver implements EntityManagerResolver { @PersistenceContext(unitName = "my") private EntityManager em; @Override public EntityManager resolveEntityManager() { return em; } }
To ask DeltaSpike data to use it just add @EntityManagerConfig:
@Repository @EntityManagerConfig(entityManagerResolver = MyUnitResolver.class) public interface MyRepository extends EntityRepository<User, Long> { }
Now we have a repo ready to work with raw entities. To use DTOs you need to provide a mapper. To do so you need to implement org.apache.deltaspike.data.api.mapping.QueryInOutMapper. Note: org.apache.deltaspike.data.api.mapping.SimpleQueryInOutMapperBase is an utility class which is more end user oriented and simplifies this implementation.
Here my implementation for the User/UserDto classes:
@ApplicationScoped public class UserMapper extends SimpleQueryInOutMapperBase<User, UserDto> { @Override protected UserDto toDto(final User user) { final UserDto userDto = new UserDto(); userDto.setName(user.getName()); userDto.setId(user.getId()); return userDto; } @Override protected User toEntity(final UserDto dto) { final User user = new User(); user.setName(dto.getName()); // I chose to not set the id here but it could be done return user; } }
Now we just need to configure our repository to use it using @MappingConfig:
@Repository(forEntity = User.class) @MappingConfig(UserMapper.class) @EntityManagerConfig(entityManagerResolver = MyUnitResolver.class) public interface MyRepository extends EntityRepository<UserDto, Long> { }
And here we are, now we can use our repository with our Dto and the JPA part is done by DeltaSpike:
@javax.ejb.Singleton public class Demo { @Inject private MyRepository repo; public UserDto run(final UserDto user) { return repo.saveAndFlush(user); } }
Want more content ? Keep up-to-date on my new blog
Or stay in touch on twitter @rmannibucau