1 package net.sumaris.core.dao.technical.jpa;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.querydsl.jpa.impl.JPAQuery;
26 import net.sumaris.core.config.SumarisConfiguration;
27 import net.sumaris.core.dao.technical.Daos;
28 import net.sumaris.core.dao.technical.SortDirection;
29 import net.sumaris.core.dao.technical.model.IEntity;
30 import net.sumaris.core.exception.SumarisTechnicalException;
31 import org.hibernate.LockOptions;
32 import org.hibernate.Session;
33 import org.hibernate.dialect.Dialect;
34 import org.springframework.beans.factory.annotation.Autowired;
35 import org.springframework.dao.DataAccessResourceFailureException;
36 import org.springframework.dao.DataIntegrityViolationException;
37 import org.springframework.data.domain.PageRequest;
38 import org.springframework.data.domain.Pageable;
39 import org.springframework.data.domain.Sort;
40 import org.springframework.data.jpa.domain.Specification;
41 import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
42 import org.springframework.data.repository.NoRepositoryBean;
43
44 import javax.persistence.EntityManager;
45 import javax.persistence.LockModeType;
46 import javax.sql.DataSource;
47 import java.io.Serializable;
48 import java.sql.SQLException;
49 import java.sql.Timestamp;
50 import java.util.Arrays;
51
52
53
54
55 public class SumarisJpaRepositoryImpl<T, ID extends Serializable>
56 extends SimpleJpaRepository<T, ID>
57 implements SumarisJpaRepository<T, ID> {
58
59 private boolean debugEntityLoad = false;
60
61 private EntityManager entityManager;
62
63 @Autowired
64 private DataSource dataSource;
65
66
67 public SumarisJpaRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
68 super(domainClass, entityManager);
69
70
71 this.entityManager = entityManager;
72
73 }
74
75 @Override
76 public T createEntity() {
77 try {
78 return getDomainClass().newInstance();
79 } catch (Exception e) {
80 throw new RuntimeException(e);
81 }
82 }
83
84 @SuppressWarnings("unchecked")
85 @Override
86 public <C extends Serializable> C load(Class<C> clazz, Serializable id) {
87
88 if (debugEntityLoad) {
89 C load = entityManager.find(clazz, id);
90 if (load == null) {
91 throw new DataIntegrityViolationException("Unable to load entity " + clazz.getName() + " with identifier '" + id + "': not found in database.");
92 }
93 }
94 return entityManager.unwrap(Session.class).load(clazz, id);
95 }
96
97
98
99
100
101
102
103
104
105 @SuppressWarnings("unchecked")
106 public <C extends Serializable> C get(Class<? extends C> clazz, Serializable id) {
107 return this.entityManager.find(clazz, id);
108 }
109
110
111
112
113
114
115
116
117
118
119 @SuppressWarnings("unchecked")
120 public <C extends Serializable> C get(Class<? extends C> clazz, Serializable id, LockModeType lockModeType) {
121 C entity = entityManager.find(clazz, id);
122 entityManager.lock(entity, lockModeType);
123 return entity;
124 }
125
126
127
128 protected EntityManager getEntityManager() {
129 return entityManager;
130 }
131
132 protected Timestamp getDatabaseCurrentTimestamp() {
133
134 if (dataSource == null) return new Timestamp(System.currentTimeMillis());
135
136 try {
137 final Dialect dialect = Dialect.getDialect(SumarisConfiguration.getInstance().getConnectionProperties());
138 final String sql = dialect.getCurrentTimestampSelectString();
139 Object r = Daos.sqlUnique(dataSource, sql);
140 return Daos.toTimestampFromJdbcResult(r);
141 } catch (DataAccessResourceFailureException | SQLException e) {
142 throw new SumarisTechnicalException(e);
143 }
144 }
145
146 protected <T> JPAQuery<T> createQuery() {
147 return new JPAQuery<>(entityManager);
148 }
149
150 protected <T extends IEntity<?>> Specification<T> and(Specification<T>... specs) {
151 Specification<T> result = null;
152 for (Specification<T> item: specs) {
153 if (item != null) {
154 if (result == null) {
155 result = Specification.where(item);
156 }
157 else {
158 result.and(item);
159 }
160 }
161 }
162 return result;
163 }
164
165 protected Pageable getPageable(int offset, int size, String sortAttribute, SortDirection sortDirection) {
166 if (sortAttribute != null) {
167 return PageRequest.of(offset / size, size,
168 (sortDirection == null) ? Sort.Direction.ASC :
169 Sort.Direction.fromString(sortDirection.toString()),
170 sortAttribute);
171 }
172 return PageRequest.of(offset / size, size);
173 }
174 }