package org.zstack.core.db; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.zstack.header.message.APIListMessage; import javax.persistence.Entity; import javax.persistence.TypedQuery; import java.lang.reflect.Field; import java.util.List; public class DbEntityListerImpl implements DbEntityLister { @Autowired private DatabaseFacade dbf; private String getEntityName(Class<?> clazz) { if (!clazz.isAnnotationPresent(Entity.class)) { throw new IllegalArgumentException(String.format("%s is not a JPA entity, @Entity is not presented on class declaration", clazz.getName())); } return clazz.getSimpleName(); } @Override public <T> List<T> listByApiMessage(APIListMessage msg, Class<T> clazz) { return listByUuids(msg.getUuids(), msg.getOffset(), msg.getLength(), clazz); } @Override public <T> List<T> listAll(Class<T> clazz) { return listAll(0, Integer.MAX_VALUE, clazz); } @Override public <T> List<T> listAll(int offset, int length, Class<T> clazz) { return listByUuids(null, offset, length, clazz); } @Override public <T> List<T> listByUuids(List<String> uuids, Class<T> clazz) { return listByUuids(uuids, 0, Integer.MAX_VALUE, clazz); } private void checkIfHasUuid(Class<?> c) { Class<?> clazz = c; do { Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (f.getName().equals("uuid")) { return; } } clazz = clazz.getSuperclass(); } while (clazz != null & clazz != Object.class); throw new IllegalArgumentException(String.format("Entity doesn't have field 'uuid'", clazz.getName())); } @Override @Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW) public <T> List<T> listByUuids(List<String> uuids, int offset, int length, Class<T> clazz) { String ename = getEntityName(clazz); String sql = null; TypedQuery<T> query = null; if (uuids == null || uuids.isEmpty()) { sql = String.format("select e from %s e", ename); query = dbf.getEntityManager().createQuery(sql, clazz); } else { checkIfHasUuid(clazz); sql = String.format("select e from %s e where e.uuid in :uuids", ename); query = dbf.getEntityManager().createQuery(sql, clazz); query.setParameter("uuids", uuids); } query.setFirstResult(offset); query.setMaxResults(length); return query.getResultList(); } }