This project is no longer being maintained (however, the released artifacts will still remain in Maven Central). JAX-RS is simply not created to be extendable/composable (eg. it is impossible to overload a JAX-RS method with different @QueryParam
s).
Provides extendable classes/interfaces to create JAX-RS CRUD Web Services from JPA entity classes.
The generated JAX-RS Web Services will contain:
- A
POST
method to insert a row - A
GET
method to query all rows - A
/{id}
GET
method to query a row by id - A
/{from}/{to}
GET
method to query rows within the given range of ids - A
/count
GET
method to query the number of rows - A
PUT
method to update a row - A
/{id}
DELETE
method to delete a row
Dependency | Version |
---|---|
JPA | 2.X.X |
JAX-RS | 2.X |
JTA | 1.2 |
The easiest way to provide the implementation for all the dependencies is to use a Java EE container (eg. WildFly).
Version 3.0.0+ no longer depends on Java EE or CDI (Contexts and Dependency Injection). You can now use this outside of a Java EE container, as long as a JPA, JAX-RS and JTA implementation is provided (eg. Hibernate + Jersey + Narayana).
Add the following to your Maven dependency list:
<dependency>
<groupId>com.github.daniel-shuy</groupId>
<artifactId>jax-rs-jpa-crud</artifactId>
<version>4.0.0</version>
</dependency>
All CRUD database tables must have a sequential number Surrogate Primary Key.
For each CRUD database table:
- Create a JPA Entity Class that extends
com.github.daniel.shuy.ws.rs.jpa.crud.EntityCRUD
, without a field for the Primary Key (already mapped inEntityCRUD
). - Create a Repository Class that implements
com.github.daniel.shuy.ws.rs.jpa.crud.RepositoryCRUD
- Create a JAX-RS Resource Class that implements
com.github.daniel.shuy.ws.rs.jpa.crud.ResourceCRUD
.
Resource/Repository Classes can be further customized/extended by implementing additional methods.
@Entity
@Table(name = "user")
@XmlRootElement
public class User extends EntityCRUD {
private static final long serialVersionUID = 1L;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
public User() {
}
public User(Long id) {
super(id);
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- Override
getEntityClass
to provide the JPA Entity Class. - Override
getEntityManager
to provide the JPA EntityManager instance to use. How to provide the EntityManager instance depends on your environment.
- Requires Contexts and Dependency Injection (CDI)
@RequestScoped
public class UserRepository implements RepositoryCRUD<User> {
@PersistenceContext(name = "persistence-unit") // name is Persistence Unit Name configured in persistence.xml
private EntityManager entityManager;
@Override
public EntityManager getEntityManager() {
return entityManager;
}
@Override
public Class<User> getEntityClass() {
return User.class;
}
}
- Requires Repository Class to be an Enterprise JavaBean (EJB)
@Stateless
@LocalBean
public class UserRepository implements RepositoryCRUD<User> {
@PersistenceContext(name = "persistence-unit") // name is Persistence Unit Name configured in persistence.xml
private EntityManager entityManager;
@Override
public EntityManager getEntityManager() {
return entityManager;
}
@Override
public Class<User> getEntityClass() {
return User.class;
}
}
- A new
EntityManager
instance needs to be created for eachRepositoryCRUD
instance, becauseEntityManager
is not thread-safe.
public class UserRepository implements RepositoryCRUD<User> {
// argument is Persistence Unit Name configured in persistence.xml
private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistence-unit");
private final EntityManager entityManager;
public UserRepository() {
entityManager = factory.createEntityManager();
}
@Override
public EntityManager getEntityManager() {
return entityManager;
}
@Override
public Class<User> getEntityClass() {
return User.class;
}
}
@Path("/user")
public class UserResource extends ResourceCRUD<User> {
@Inject
private UserRepository repository;
@Override
public RepositoryCRUD<User> getRepository() {
return repository;
}
}
@Path("/user")
public class UserResource extends ResourceCRUD<User> {
@EJB
private UserRepository repository;
@Override
public RepositoryCRUD<User> getRepository() {
return repository;
}
}
- A new
RepositoryCRUD
instance needs to be explicitly created on each call togetRepository()
, since we don't have CDI's @RequestScoped or EJB's @Stateless.
@Path("/user")
public class UserResource extends ResourceCRUD<User> {
@Override
public RepositoryCRUD<User> getRepository() {
return new UserRepository();
}
}