Skip to content

Commit 9d727df

Browse files
author
Gerald Unterrainer
committed
Merge branch 'features/sql-query-enhancements' into develop
2 parents 73bcdb8 + ca656dd commit 9d727df

28 files changed

+939
-504
lines changed

src/main/java/info/unterrainer/commons/httpserver/GenericHandlerGroup.java

+13-14
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
import java.util.Map.Entry;
88
import java.util.concurrent.ExecutorService;
99

10-
import info.unterrainer.commons.httpserver.daos.BasicDao;
10+
import info.unterrainer.commons.httpserver.daos.CoreDao;
1111
import info.unterrainer.commons.httpserver.daos.DaoTransaction;
12-
import info.unterrainer.commons.httpserver.daos.DaoTransactionManager;
1312
import info.unterrainer.commons.httpserver.enums.Attribute;
1413
import info.unterrainer.commons.httpserver.enums.Endpoint;
1514
import info.unterrainer.commons.httpserver.enums.QueryField;
@@ -33,10 +32,9 @@
3332
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
3433
public class GenericHandlerGroup<P extends BasicJpa, J extends BasicJson, E> implements HandlerGroup {
3534

36-
private final BasicDao<P, E> dao;
35+
private final CoreDao<P, E> dao;
3736
private final Class<P> jpaType;
3837
private final Class<J> jsonType;
39-
private final DaoTransactionManager<E> daoTransactionManager;
4038
private final JsonMapper jsonMapper;
4139
private final MapperFacade orikaMapper;
4240
private final String path;
@@ -47,7 +45,7 @@ public class GenericHandlerGroup<P extends BasicJpa, J extends BasicJson, E> imp
4745
private final ExecutorService executorService;
4846
private final HandlerUtils hu = new HandlerUtils();
4947
private final String tenantIdRowName;
50-
private final BasicDao<? extends BasicJpa, E> tenantDao;
48+
private final CoreDao<? extends BasicJpa, E> tenantDao;
5149
private final Class<? extends BasicJpa> tenantJpaType;
5250
private final String fieldRowName;
5351
private final String tenantRowName;
@@ -97,7 +95,7 @@ private Role[] rolesFor(final List<Endpoint> endpointList) {
9795
}
9896

9997
private void getEntry(final Context ctx) {
100-
DaoTransaction<E> transaction = daoTransactionManager.beginTransaction();
98+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
10199

102100
P jpa = hu.getJpaById(ctx, transaction.getManager(), dao);
103101
J json = orikaMapper.map(jpa, jsonType);
@@ -130,7 +128,7 @@ private void getList(final Context ctx) {
130128
e.getMessage());
131129
}
132130

133-
DaoTransaction<E> transaction = daoTransactionManager.beginTransaction();
131+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
134132

135133
ListJson<P> bList = dao.getList(transaction.getManager(), offset, size, interceptorResult.getSelectClause(),
136134
interceptorResult.getJoinClause(), interceptorResult.getWhereClause(), interceptorResult.getParams(),
@@ -152,7 +150,7 @@ private void create(final Context ctx) throws IOException {
152150
try {
153151
J json = jsonMapper.fromStringTo(jsonType, b);
154152
P mappedJpa = orikaMapper.map(json, jpaType);
155-
DaoTransaction<E> transaction = daoTransactionManager.beginTransaction();
153+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
156154

157155
mappedJpa = extensions.runPreInsert(ctx, transaction.getManager(), json, mappedJpa, executorService);
158156
P createdJpa = dao.create(transaction.getManager(), mappedJpa);
@@ -170,38 +168,39 @@ private void create(final Context ctx) throws IOException {
170168
}
171169

172170
private void fullUpdate(final Context ctx) throws IOException {
173-
P jpa = hu.getJpaById(ctx, dao);
171+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
172+
P jpa = hu.getJpaById(ctx, transaction.getManager(), dao);
174173
try {
175174
J json = jsonMapper.fromStringTo(jsonType, ctx.body());
176175
P mappedJpa = orikaMapper.map(json, jpaType);
177176
mappedJpa.setId(jpa.getId());
178177
mappedJpa.setCreatedOn(jpa.getCreatedOn());
179178
mappedJpa.setEditedOn(jpa.getEditedOn());
180-
DaoTransaction<E> transaction = daoTransactionManager.beginTransaction();
181179

182180
mappedJpa = extensions.runPreModify(ctx, transaction.getManager(), jpa.getId(), json, jpa, mappedJpa,
183181
executorService);
184-
P persistedJpa = dao.update(mappedJpa);
182+
P persistedJpa = dao.update(transaction.getManager(), mappedJpa);
185183

186184
J r = orikaMapper.map(persistedJpa, jsonType);
187185
r = extensions.runPostModify(ctx, transaction.getManager(), jpa.getId(), json, jpa, mappedJpa, persistedJpa,
188186
r, executorService);
189187

190-
transaction.end();
191188
ctx.attribute(Attribute.RESPONSE_OBJECT, r);
192189

193190
} catch (JsonProcessingException | JsonMappingException e) {
194191
throw new BadRequestException();
192+
} finally {
193+
transaction.end();
195194
}
196195
}
197196

198197
private void delete(final Context ctx) {
199198
ctx.attribute(Attribute.RESPONSE_OBJECT, null);
200199
Long id = hu.checkAndGetId(ctx);
201-
DaoTransaction<E> transaction = daoTransactionManager.beginTransaction();
200+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
202201

203202
id = extensions.runPreDelete(ctx, transaction.getManager(), id, executorService);
204-
dao.delete(id);
203+
dao.delete(transaction.getManager(), id);
205204
ctx.status(204);
206205
extensions.runPostDelete(ctx, transaction.getManager(), id, executorService);
207206

src/main/java/info/unterrainer/commons/httpserver/GenericHandlerGroupBuilder.java

+6-13
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
import java.util.List;
77
import java.util.concurrent.ExecutorService;
88

9-
import info.unterrainer.commons.httpserver.daos.BasicDao;
10-
import info.unterrainer.commons.httpserver.daos.DaoTransactionManager;
9+
import info.unterrainer.commons.httpserver.daos.CoreDao;
1110
import info.unterrainer.commons.httpserver.daos.ParamMap;
1211
import info.unterrainer.commons.httpserver.enums.Endpoint;
1312
import info.unterrainer.commons.httpserver.interceptors.InterceptorData;
@@ -28,10 +27,9 @@
2827
public class GenericHandlerGroupBuilder<P extends BasicJpa, J extends BasicJson, E> {
2928

3029
private final HttpServer server;
31-
private BasicDao<P, E> dao;
3230
private final Class<P> jpaType;
3331
private final Class<J> jsonType;
34-
private final DaoTransactionManager<E> daoTransactionManager;
32+
private final CoreDao<P, E> dao;
3533
private JsonMapper jsonMapper;
3634
private MapperFactory orikaFactory;
3735
private String path;
@@ -42,7 +40,7 @@ public class GenericHandlerGroupBuilder<P extends BasicJpa, J extends BasicJson,
4240
private String tenantIdRowName;
4341
private String tenantRowName;
4442
private String tenantFieldRowName;
45-
private BasicDao<? extends BasicJpa, E> tenantDao;
43+
private CoreDao<? extends BasicJpa, E> tenantDao;
4644
private Class<? extends BasicJpa> tenantJpaType;
4745

4846
HandlerExtensions<P, J, E> extensions = new HandlerExtensions<>();
@@ -56,8 +54,8 @@ public HttpServer add() {
5654
if (executorService == null)
5755
executorService = server.executorService;
5856
GenericHandlerGroup<P, J, E> handlerGroupInstance = new GenericHandlerGroup<>(dao, jpaType, jsonType,
59-
daoTransactionManager, jsonMapper, orikaFactory.getMapperFacade(), path, endpoints, getListInterceptors,
60-
extensions, accessRoles, executorService, tenantIdRowName, tenantDao, tenantJpaType, tenantFieldRowName,
57+
jsonMapper, orikaFactory.getMapperFacade(), path, endpoints, getListInterceptors, extensions,
58+
accessRoles, executorService, tenantIdRowName, tenantDao, tenantJpaType, tenantFieldRowName,
6159
tenantRowName);
6260
server.addHandlerGroup(handlerGroupInstance);
6361
return server;
@@ -78,7 +76,7 @@ public GenericHandlerGroupBuilder<P, J, E> isMultiTenantEnabledByIdRow(final Str
7876
}
7977

8078
public <TP extends BasicJpa> GenericHandlerGroupBuilder<P, J, E> isMultiTenantEnabledByTable(
81-
final BasicDao<TP, E> tenantDao, final Class<TP> tenantJpaType, final String fieldRowName,
79+
final CoreDao<TP, E> tenantDao, final Class<TP> tenantJpaType, final String fieldRowName,
8280
final String tenantRowName) {
8381
this.tenantDao = tenantDao;
8482
this.tenantJpaType = tenantJpaType;
@@ -87,11 +85,6 @@ public <TP extends BasicJpa> GenericHandlerGroupBuilder<P, J, E> isMultiTenantEn
8785
return this;
8886
}
8987

90-
public GenericHandlerGroupBuilder<P, J, E> dao(final BasicDao<P, E> dao) {
91-
this.dao = dao;
92-
return this;
93-
}
94-
9588
public GenericHandlerGroupBuilder<P, J, E> jsonMapper(final JsonMapper jsonMapper) {
9689
this.jsonMapper = jsonMapper;
9790
return this;

src/main/java/info/unterrainer/commons/httpserver/HandlerUtils.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import java.time.format.DateTimeFormatter;
55
import java.time.format.DateTimeParseException;
66

7-
import info.unterrainer.commons.httpserver.daos.BasicDao;
7+
import info.unterrainer.commons.httpserver.daos.CoreDao;
8+
import info.unterrainer.commons.httpserver.daos.DaoTransaction;
89
import info.unterrainer.commons.httpserver.enums.QueryField;
910
import info.unterrainer.commons.httpserver.exceptions.BadRequestException;
1011
import info.unterrainer.commons.httpserver.exceptions.NotFoundException;
@@ -19,20 +20,25 @@ public Long checkAndGetId(final Context ctx) {
1920
return convertToLong(s);
2021
}
2122

22-
public <P extends BasicJpa, E> P getJpaById(final Context ctx, final E entityManager, final BasicDao<P, E> dao) {
23+
public <P extends BasicJpa, E> P getJpaById(final Context ctx, final E manager, final CoreDao<P, E> dao) {
2324
Long id = checkAndGetId(ctx);
24-
P jpa = dao.getById(entityManager, id);
25+
P jpa = dao.getById(manager, id);
2526
if (jpa == null)
2627
throw new NotFoundException();
2728
return jpa;
2829
}
2930

30-
public <P extends BasicJpa, E> P getJpaById(final Context ctx, final BasicDao<P, E> dao) {
31+
public <P extends BasicJpa, E> P getJpaById(final Context ctx, final CoreDao<P, E> dao) {
3132
Long id = checkAndGetId(ctx);
32-
P jpa = dao.getById(id);
33-
if (jpa == null)
34-
throw new NotFoundException();
35-
return jpa;
33+
DaoTransaction<E> transaction = dao.getTransactionManager().beginTransaction();
34+
try {
35+
P jpa = dao.getById(transaction.getManager(), id);
36+
if (jpa == null)
37+
throw new NotFoundException();
38+
return jpa;
39+
} finally {
40+
transaction.end();
41+
}
3642
}
3743

3844
public <J> void setPaginationParamsFor(final ListJson<J> jList, final long offset, final long pageSize,

src/main/java/info/unterrainer/commons/httpserver/HttpServer.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import org.eclipse.jetty.server.ServerConnector;
1717

1818
import info.unterrainer.commons.httpserver.accessmanager.HttpAccessManager;
19-
import info.unterrainer.commons.httpserver.daos.DaoTransactionManager;
19+
import info.unterrainer.commons.httpserver.daos.CoreDaoProvider;
2020
import info.unterrainer.commons.httpserver.enums.Attribute;
2121
import info.unterrainer.commons.httpserver.enums.ResponseType;
2222
import info.unterrainer.commons.httpserver.exceptions.HttpException;
@@ -98,8 +98,8 @@ public void addHandlerGroup(final HandlerGroup group) {
9898
}
9999

100100
public <P extends BasicJpa, J extends BasicJson, E> GenericHandlerGroupBuilder<P, J, E> handlerGroupFor(
101-
final Class<P> jpaType, final Class<J> jsonType, final DaoTransactionManager<E> daoTransactionManager) {
102-
return new GenericHandlerGroupBuilder<>(this, jpaType, jsonType, daoTransactionManager);
101+
final Class<P> jpaType, final Class<J> jsonType, final CoreDaoProvider<P, E> coreDaoProvider) {
102+
return new GenericHandlerGroupBuilder<>(this, jpaType, jsonType, coreDaoProvider.getCoreDao());
103103
}
104104

105105
private void create() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package info.unterrainer.commons.httpserver.daos;
2+
3+
import javax.persistence.EntityManagerFactory;
4+
5+
import info.unterrainer.commons.rdbutils.entities.BasicAsyncJpa;
6+
7+
public class AsyncJpqlDao<P extends BasicAsyncJpa> extends BasicJpqlDao<P> {
8+
9+
/**
10+
* Generates a DAO that lets you build and execute queries.
11+
*
12+
* @param emf the {@link EntityManagerFactory} to use
13+
* @param type the return-type of the query (the underlying JPA)
14+
*/
15+
public AsyncJpqlDao(final EntityManagerFactory emf, final Class<P> type) {
16+
super(emf, type);
17+
}
18+
19+
/**
20+
* Build a SELECT(*)-like query. The result will be of the underlying generic
21+
* type.
22+
*
23+
* @return a query-builder
24+
*/
25+
public AsyncListQueryBuilder<P, P> select() {
26+
return new AsyncListQueryBuilder<>(emf, this, type);
27+
}
28+
29+
/**
30+
* Build a SELECT(*)-like query. The result will be of the given type (use this
31+
* for a COUNT(*) query, for example).
32+
*
33+
* @param <T> the type the result will be
34+
* @param resultType the type the result will be
35+
* @return a query-builder
36+
*/
37+
public <T> AsyncListQueryBuilder<P, T> select(final Class<T> resultType) {
38+
return new AsyncListQueryBuilder<>(emf, this, resultType);
39+
}
40+
41+
/**
42+
* Build a SELECT-query with a custom select-clause. The result will be of the
43+
* given type (use this for a COUNT(*) query, for example).
44+
*
45+
* @param <T> the type the result will be
46+
* @param selectClause your custom select-clause (the base-object has the alias
47+
* 'o'. So the default would be "o" internally resulting in
48+
* a "SELECT o")
49+
* @param resultType the type the result will be
50+
* @return a query-builder
51+
*/
52+
public <T> AsyncListQueryBuilder<P, T> select(final String selectClause, final Class<T> resultType) {
53+
AsyncListQueryBuilder<P, T> b = new AsyncListQueryBuilder<>(emf, this, resultType);
54+
b.setSelect(selectClause);
55+
return b;
56+
}
57+
58+
/**
59+
* Build a SELECT-query with a custom select-clause. The result will be of the
60+
* underlying generic type.
61+
*
62+
* @param selectClause your custom select-clause (the base-object has the alias
63+
* 'o'. So the default would be "o" internally resulting in
64+
* a "SELECT o")
65+
* @return a query-builder
66+
*/
67+
public AsyncListQueryBuilder<P, P> select(final String selectClause) {
68+
AsyncListQueryBuilder<P, P> b = new AsyncListQueryBuilder<>(emf, this, type);
69+
b.setSelect(selectClause);
70+
return b;
71+
}
72+
73+
/**
74+
* Get an element by ID.
75+
*
76+
* @param id the ID to fetch.
77+
* @return the element with the given ID or null, if there was no such thing
78+
*/
79+
public SingleQueryBuilder<P, P> select(final Long id) {
80+
return new SingleQueryBuilder<>(this, id);
81+
}
82+
83+
/**
84+
* Insert the given entity.
85+
*
86+
* @param entity to insert.
87+
* @return the entity after inserting
88+
*/
89+
public InsertQueryBuilder<P> insert(final P entity) {
90+
return new InsertQueryBuilder<>(this, entity);
91+
}
92+
93+
/**
94+
* Update the given entity.
95+
*
96+
* @param entity to update.
97+
* @return the entity after updating
98+
*/
99+
public UpdateQueryBuilder<P> update(final P entity) {
100+
return new UpdateQueryBuilder<>(this, entity);
101+
}
102+
}

src/main/java/info/unterrainer/commons/httpserver/daos/QueryAsyncBuilder.java src/main/java/info/unterrainer/commons/httpserver/daos/AsyncListQueryBuilder.java

+6-30
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,22 @@
44
import java.util.HashSet;
55
import java.util.Set;
66

7-
import javax.persistence.EntityManager;
87
import javax.persistence.EntityManagerFactory;
9-
import javax.persistence.TypedQuery;
108

119
import info.unterrainer.commons.rdbutils.entities.BasicAsyncJpa;
1210
import info.unterrainer.commons.rdbutils.enums.AsyncState;
1311

14-
public class QueryAsyncBuilder<P extends BasicAsyncJpa, T> extends BasicQueryBuilder<P, T, QueryAsyncBuilder<P, T>>
15-
implements QueryInterface<P, T> {
12+
public class AsyncListQueryBuilder<P extends BasicAsyncJpa, T>
13+
extends BasicListQueryBuilder<P, T, AsyncListQueryBuilder<P, T>> implements QueryInterface<P, T> {
1614

1715
private Set<AsyncState> asyncStates = new HashSet<>();
1816

19-
QueryAsyncBuilder(final EntityManagerFactory emf, final JpqlAsyncDao<P> dao, final Class<T> resultType) {
17+
AsyncListQueryBuilder(final EntityManagerFactory emf, final AsyncJpqlDao<P> dao, final Class<T> resultType) {
2018
super(emf, dao, resultType);
2119
}
2220

23-
@Override
24-
public Query<P, T> build() {
25-
return new Query<>(emf, this);
21+
public ListQuery<P, T> build() {
22+
return new ListQuery<>(emf, this);
2623
}
2724

2825
/**
@@ -40,29 +37,8 @@ public Query<P, T> build() {
4037
* @param asyncStates a single or number of AsyncState values
4138
* @return an instance of this builder to provide a fluent interface
4239
*/
43-
public QueryAsyncBuilder<P, T> asyncStateOf(final AsyncState... asyncStates) {
40+
public AsyncListQueryBuilder<P, T> asyncStateOf(final AsyncState... asyncStates) {
4441
this.asyncStates.addAll(Arrays.asList(asyncStates));
4542
return this;
4643
}
47-
48-
@Override
49-
public TypedQuery<T> getTypedQuery(final EntityManager em) {
50-
return dao.getQuery(em, selectClause, joinClause, whereClause, parameters, resultType, orderByClause,
51-
lockPessimistic, asyncStates);
52-
}
53-
54-
@Override
55-
public javax.persistence.Query getCountQuery(final EntityManager em) {
56-
return dao.getCountQuery(em, selectClause, joinClause, whereClause, parameters, asyncStates);
57-
}
58-
59-
@Override
60-
public EntityManager getEntityManager() {
61-
return entityManager;
62-
}
63-
64-
@Override
65-
public BasicJpqlDao<P> getDao() {
66-
return dao;
67-
}
6844
}

0 commit comments

Comments
 (0)