Skip to content

Instantly share code, notes, and snippets.

@mcgivrer
Last active June 7, 2016 12:34
Show Gist options
  • Save mcgivrer/4080a2173fffc2f9826a643092ad95e6 to your computer and use it in GitHub Desktop.
Save mcgivrer/4080a2173fffc2f9826a643092ad95e6 to your computer and use it in GitHub Desktop.
JPA Light Generic repository from scratch
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.webcontext.apps.thegame.util.FileIO;
/**
* THis GenericRepository implements basic method for CRUD operation.
*
* @author Frédéric Delorme<[email protected]>
*
* @param <T>
* @param <PK>
*/
public class GenericRepository<T, PK> implements IRepository<T, PK> {
@Inject
protected EntityManager em;
/**
* Date formatter to be used to convert date in serialize/deserialize
* operations.
*/
protected Gson gson = new GsonBuilder()
.setDateFormat("YYYY-mm-dd hh:MM:SS").create();
/**
* This is the container for the Class of the <T> parameter.
*/
protected Class<T> inferedClass;
@SuppressWarnings("unchecked")
public Class<T> getGenericClass() throws ClassNotFoundException {
if (inferedClass == null) {
Type mySuperclass = getClass().getGenericSuperclass();
Type tType = ((ParameterizedType) mySuperclass)
.getActualTypeArguments()[0];
String className = tType.toString().split(" ")[1];
inferedClass = (Class<T>) Class.forName(className);
}
return inferedClass;
}
public GenericRepository() {
super();
}
T entity;
@Override
public T retrieve(Long id) throws ClassNotFoundException {
return em.find(getGenericClass(), id);
}
@Override
public T create(T entity) throws Exception {
em.persist(entity);
em.flush();
return entity;
}
@Override
public T update(T entity) throws Exception {
entity = em.merge(entity);
em.flush();
return entity;
}
@Override
public void delete(T entity) throws Exception {
em.remove(entity);
em.flush();
}
@Override
public List<T> findAll(int offset, int pageSize) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> criteria = cb.createQuery(inferedClass);
Root<T> entity = criteria.from(inferedClass);
criteria.select(entity).orderBy(cb.asc(entity.get("title")));
return em.createQuery(criteria).getResultList();
}
/**
* Count the number of entities <T> in database.
*
* @return
*/
public long count() {
CriteriaQuery<Long> cq = null;
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
cq = qb.createQuery(Long.class);
cq.select(qb.count(cq.from(getGenericClass())));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return em.createQuery(cq).getSingleResult();
}
/**
* Read the T object list from a JSON file name <code>filePath</code>, and
* if <code>storeToDabase</code> is true, store loaded object to
* corresponding entity.
*
* @param filePath
* the JSON file to be read and parsed to produce a
* <code>List<T></code> objects.
* @param storeToDatabase
* a flag set to true if you need to store data from
* <code>filePath</code> to database.
* @return return a list of T object as a <code>list<T></code>.
* @throws Exception
*/
public List<T> loadObjectFromJSONFile(String filePath,
boolean storeToDatabase) throws Exception {
URL path = Thread.currentThread().getContextClassLoader()
.getResource("/");
System.out.println("dataset path"+path.getPath());
String json = FileIO.fastRead(filePath);
/*
* TypeToken<List<T>> token = new TypeToken<List<T>>() { }; List<T> list
* = gson.fromJson(json, token.getType()); for (T entity : list) {
* this.create(entity); }
*/
ArrayList<T> list = gson.fromJson(json, new TypeToken<ArrayList<T>>() {
}.getType());
for (int i = 0, size = list.size(); i < size; i++) {
T entity = gson.fromJson(gson.toJson(list.get(i)),
getGenericClass());
update(entity);
list.set(i, entity);
}
return list;
}
}
import java.util.List;
/**
* INterface to describe basic needed operations to implements to provide some
* CRUD operation.
* <ul>
* <li><strong>C</strong>reate : create a new entity in the persistence system,</li>
* <li><strong>R</strong>etrieve operation can retrieve one or more entity,</li>
* <li><strong>U</strong>pdate can update an existing entity,</li>
* <li><strong>D</strong>elete an existing entity from the perisstence system.</li>
* </ul>
*
* @author Frédéric Delorme<[email protected]>
*
* @param <T>
* @param <PK>
*/
public interface IRepository<T, PK> {
/**
* Find an entity <T> on its primary key value <PK>
*
* @param id
* the unique identifier <PK> for the entity to be retrieved.
* @return return the corresponding entity <T> to the id key <PK> value.
*/
public abstract T retrieve(Long id) throws ClassNotFoundException;
/**
* Retrieve all entities <T> from the persistence system.
*
* @param id
* @param offset
* @param pageSize
* @return
*/
public abstract List<T> findAll(int offset, int pageSize);
/**
* persist the entity <T> to the persistence system. an Id will be generated
* according to the id policy in the Entity id attribute .
*
* @param entity
* the entity <T> to persist.
* @return the entity <T> just created with its new id<PK>.
* @throws Exception
*/
public abstract T create(T entity) throws Exception;
/**
* update an existing entity.
*
* @param entity
* the entity <T> to be updated.
* @return
* @throws Exception
*/
public abstract T update(T entity) throws Exception;
/**
* Delete the entity from the persistence system.
*
* @param entity
* the entity <T> to be deleted.
* @throws Exception
*/
public abstract void delete(T entity) throws Exception;
}
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
/**
* User for the TheGame application. this entity is used to identitied user
* account on the web site.
*
* @author Frédéric Delorme<[email protected]>
*
*/
@SuppressWarnings("serial")
@Entity
@XmlRootElement
@Table(name = "GAMEUSERS", uniqueConstraints = @UniqueConstraint(columnNames = "email"))
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
@NotNull
@Size(min = 1, max = 25)
@Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
private String username;
@Size(min = 1, max = 40)
@Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
private String firstname;
@Size(min = 1, max = 40)
@Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
private String lastname;
@NotNull
@Size(min = 8, max = 25)
private String password;
@NotNull
@NotEmpty
@Email
private String email;
@NotNull
@Size(min = 10, max = 12)
@Digits(fraction = 0, integer = 12)
@Column(name = "phone_number")
private String phoneNumber;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String name) {
this.username = name;
}
/**
* @return the firstname
*/
public String getFirstname() {
return firstname;
}
/**
* @param firstname the firstname to set
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* @return the lastname
*/
public String getLastname() {
return lastname;
}
/**
* @param lastname the lastname to set
*/
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("User [");
if (id != null)
builder.append("id=").append(id).append(", ");
if (username != null)
builder.append("username=").append(username).append(", ");
if (firstname != null)
builder.append("firstname=").append(firstname).append(", ");
if (lastname != null)
builder.append("lastname=").append(lastname).append(", ");
if (password != null)
builder.append("password=").append(password).append(", ");
if (email != null)
builder.append("email=").append(email).append(", ");
if (phoneNumber != null)
builder.append("phoneNumber=").append(phoneNumber);
builder.append("]");
return builder.toString();
}
}
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import com.webcontext.apps.thegame.data.repository.GenericRepository;
import com.webcontext.apps.thegame.model.User;
@ApplicationScoped
public class UserRepository extends GenericRepository<User, Long> {
public User findByEmail(String email) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = cb.createQuery(User.class);
Root<User> user = criteria.from(User.class);
criteria.select(user).where(cb.equal(user.get("email"), email));
return em.createQuery(criteria).getSingleResult();
}
public List<User> findAllOrderedByName() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = cb.createQuery(User.class);
Root<User> user = criteria.from(User.class);
criteria.select(user).orderBy(cb.asc(user.get("name")));
return em.createQuery(criteria).getResultList();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment