Platonos - Platonos Projects - Enterprise

The Platonos enterprise will provide functionality to make Java EE development easier.
The project is still young so it currently doens't provide that much yet. Currently it only provides some functionality in the persistence area (JPA).
In the code snippet below you can see an interface which defines a service that defines some persistence operations on users:

@Abstract
public interface UserService {

	@CreateQuery
	public User createUser(User user);
	
	@ReadQuery(from=User.class)
	@SelectColumns(columns={"id","name"})
	public UserDto getUser(Long id);
	
	@UpdateQuery
	public User updateUser(User user);
	
	@DeleteQuery
	public void deleteUser(User user);
		
	@NamedQuery(name="userByName")
	public User getUserByName(String name);
	
	@ReadQuery()
	public User getUser(String name);
	
	@NamedQuery(name="allUsers")
	public List<User> getAllUsers();
	
	@ReadQuery
	@SelectColumns(columns={"id","name"})
	public List<UserDto> getAllUsersAsDto();
	
	@NativeSelectQuery(query="select * from User")
	public List<User> getUsers();
	
	@NativeInsertQuery(query="insert into User values(?1,?2)")
	public void insertUser(long id, String name);
}

This interface is processed during compilation and will generate an implementation of this interface. The result:

public abstract class AbstractUserService implements org.platonos.persistence.UserService {

	protected @PersistenceContext EntityManager entityManager;

	public org.platonos.persistence.User createUser(org.platonos.persistence.User user) {
		entityManager.persist(user);
		return user;
	}

	public void deleteUser(org.platonos.persistence.User user) {
		entityManager.remove(user);
	}
	
	public java.util.List<org.platonos.persistence.User> getAllUsers() {
		TypedQuery<org.platonos.persistence.User> query = entityManager.createNamedQuery("allUsers",org.platonos.persistence.User.class);
		return query.getResultList();
	}

	public java.util.List<org.platonos.persistence.UserDto> getAllUsersAsDto() {
		TypedQuery<org.platonos.persistence.UserDto> query = entityManager.createQuery("select new java.util.List<org.platonos.persistence.UserDto>(id, name) from java.util.List<org.platonos.persistence.UserDto>", org.platonos.persistence.UserDto.class);
		return query.getResultList();
	}

	public org.platonos.persistence.UserDto getUser(java.lang.Long id) {
		TypedQuery<org.platonos.persistence.UserDto> query = entityManager.createQuery("select new org.platonos.persistence.UserDto(id, name) from org.platonos.persistence.User where id = ?1", org.platonos.persistence.UserDto.class);
		query.setParameter(1,id);
		return query.getSingleResult();
	}

	public org.platonos.persistence.User getUser(java.lang.String name) {
		TypedQuery<org.platonos.persistence.User> query = entityManager.createQuery("from org.platonos.persistence.User where name = ?1", org.platonos.persistence.User.class);
		query.setParameter(1,name);
		return query.getSingleResult();
	}

	public org.platonos.persistence.User getUserByName(java.lang.String name) {
		TypedQuery<org.platonos.persistence.User> query = entityManager.createNamedQuery("userByName",org.platonos.persistence.User.class);
		query.setParameter("name", name);
		return query.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	public java.util.List<org.platonos.persistence.User> getUsers() {
		Query query = entityManager.createNativeQuery("select * from User",org.platonos.persistence.User.class);
		return query.getResultList();
	}

	public void insertUser(long id,java.lang.String name) {
		Query query = entityManager.createNativeQuery("insert into User values(?1,?2)");
		query.setParameter(1,id);
		query.setParameter(2,name);
		query.executeUpdate();
	}

	public org.platonos.persistence.User updateUser(org.platonos.persistence.User user) {
		return entityManager.merge(user);
	}
}


Abstract implementation
As you can see the an abstract class is generated, this is the result of the @Abstract annotation. By default the generated
implementation is not abstract. The implementation is never final so you can always subclass it when needed.

Source level annotations
And as you can see the generated class doesn't contains the annotations specified in the interface. The annotations
are only available during compilation so now extra runtime dependencies are added.

Return type and DTO
By default the return type of the method is inspected to determine the entity type. The @ReadQuery allows you
to specify another entity, this is useful if you want to retrieve DTO (Data Transfer Object).
When using DTO object you also have to specify the select columns by using the @SelectColumns annotation.
Some methods like read methods (@ReadQuery) support parameters, these parameters are then used in
where clause of the query. The name of the query parameters are derived from the parameters in the method signature.
An exception is the @NativeInsertQuery where the index in the parameter definition of the method signature is used.

Native queries
As you properly has noticed the interface contains native query strings. Bad practice or anti-pattern as some developers may call it. But this is done because Hibernate not always allows you to specify named native queries. We are currently into options externalize those native query strings.