Project

General

Profile

« Previous | Next » 

Revision ac512a79

Added by Andreas Müller almost 2 years ago

ref #10067, ref #10077 remove javassist as bytecode provider from cdmlib

View differences:

.gitattributes
292 292
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.testFindDeleted.xml -text
293 293
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.testGetTaxaByNameAndArea.xml -text
294 294
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImplTest.xml -text
295
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.testSortindexForJavassist-result.xml -text
296
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.testSortindexForJavassist.xml -text
297
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.testSortindexForJavassist2-result.xml -text
298 295
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.xml -text
299 296
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml -text
300 297
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSave.xml -text
cdmlib-cache/src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml
13 13
    <session-factory>
14 14

  
15 15
      <property name="connection.release_mode">after_transaction</property>
16
      
17
      <property name="hibernate.bytecode.provider">javassist</property>
18 16

  
19 17
      <property name="hibernate.implicit_naming_strategy">org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl</property>
20 18
      <!-- NOTE: if integrated in spring this is handled there (see persistence.xml) -->
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/common/ICdmEntityDao.java
25 25
import eu.etaxonomy.cdm.persistence.query.Grouping;
26 26
import eu.etaxonomy.cdm.persistence.query.MatchMode;
27 27
import eu.etaxonomy.cdm.persistence.query.OrderHint;
28
import javassist.tools.rmi.ObjectNotFoundException;
29 28

  
30 29
/**
31 30
 * Base class for all DAOs intended for persisting instances of a certain CdmBase subclass.
......
315 314
     * object usually is a proxy object except for the case when it was already initialized
316 315
     * before in the same session.<BR>
317 316
     * This methods wraps {@link Session#load(Class, java.io.Serializable)}.<BR>
318
     * It does not check, if the object really exists but throws an {@link ObjectNotFoundException}
319
     * exception when no record with the given id exists in the database.
317
     * It does not check, if the object really exists but throws an exception
318
     * when no record with the given id exists in the database.
319
     *
320 320
     * @return
321 321
     *         the (uninitialized proxy) object
322 322
     */
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/HibernateConfiguration.java
42 42
    public static final boolean REGISTER_SEARCH_DEFAULT = false;
43 43
    public static final boolean REGISTER_ENVERS_DEFAULT = true;
44 44
    public static final Class<? extends RegionFactory> CACHE_PROVIDER_DEFAULT = NoCachingRegionFactory.class;
45
    public final static String BYTECODE_PROVIDER_DEFAULT = "javassist";  //bytebuddy, TODO make it an enum
45
    public final static String BYTECODE_PROVIDER_DEFAULT = "bytebuddy";
46 46

  
47 47
    //*************************** FACTORY METHODS **************************************/
48 48

  
cdmlib-persistence/src/main/resources/eu/etaxonomy/cdm/hibernate.cfg.xml
7 7
    <session-factory>
8 8

  
9 9
      <property name="connection.release_mode">after_transaction</property>
10
      
11
      <property name="hibernate.bytecode.provider">javassist</property>
12 10

  
13 11
      <!-- Connection Pooling -->
14 12
<!--       <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> -->
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/applicationContext-testPersistentDataSource.xml
28 28
                <prop key="hibernate.format_sql">false</prop>
29 29
                <prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.impl.FSDirectoryProvider</prop>
30 30
                <prop key="hibernate.search.default.indexBase">./target/test-classes</prop>
31
                <prop key="hibernate.bytecode.provider">javassist</prop>
32 31
            </props>
33 32
        </property>
34 33
    </bean> 
cdmlib-remote-webapp/src/main/webapp/WEB-INF/datasources/configurable.xml
26 26
              <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.internal.NoCachingRegionFactory</prop>
27 27
              <prop key="hibernate.show_sql">false</prop>
28 28
              <prop key="hibernate.format_sql">false</prop>
29
              <prop key="hibernate.bytecode.provider">javassist</prop>
30 29
              <prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.impl.FSDirectoryProvider</prop>
31 30
              <prop key="hibernate.search.default.indexBase">${eu.etaxonomy.cdm.search.index.path}</prop><!-- set in applicationContext.xml -->
32 31

  
cdmlib-remote-webapp/src/main/webapp/WEB-INF/datasources/datasources-local.xml
48 48
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.internal.NoCachingRegionFactory</prop>
49 49
                <prop key="hibernate.show_sql">true</prop>
50 50
                <prop key="hibernate.format_sql">false</prop>
51
                <prop key="hibernate.bytecode.provider">javassist</prop>
52 51
            </props>
53 52
        </property>
54 53
    </bean>
cdmlib-remote-webapp/src/main/webapp/WEB-INF/datasources/empty-default-datasource.xml
33 33
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.internal.NoCachingRegionFactory</prop>
34 34
                <prop key="hibernate.show_sql">false</prop>
35 35
                <prop key="hibernate.format_sql">false</prop>
36
                <prop key="hibernate.bytecode.provider">javassist</prop>
37 36
            </props>
38 37
        </property>
39 38
    </bean>
cdmlib-remote-webapp/src/main/webapp/WEB-INF/datasources/routing-datasource.xml
66 66
              <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.internal.NoCachingRegionFactory</prop>
67 67
              <prop key="hibernate.show_sql">false</prop>
68 68
              <prop key="hibernate.format_sql">false</prop>
69
              <prop key="hibernate.bytecode.provider">javassist</prop>
70 69
              <prop key="hibernate.search.default.indexBase">${user.home}/.cdmLibrary/</prop>
71 70
            </props>
72 71
        </property>
cdmlib-remote-webapp/src/test/resources/hibernate.properties
11 11
#hibernate.show_sql=true
12 12

  
13 13
# hibernate.format_sql - default: false
14
#hibernate.format_sql=true
15

  
16
#hibernate.bytecode.provider=javassist
14
#hibernate.format_sql=true
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/IService.java
1
/**

2
* Copyright (C) 2007 EDIT

3
* European Distributed Institute of Taxonomy

4
* http://www.e-taxonomy.eu

5
*

6
* The contents of this file are subject to the Mozilla Public License Version 1.1

7
* See LICENSE.TXT at the top of this package for the full license terms.

8
*/

9

  
10
package eu.etaxonomy.cdm.api.service;

11

  
12

  
13
import java.util.Collection;

14
import java.util.List;

15
import java.util.Map;

16
import java.util.Set;

17
import java.util.UUID;

18

  
19
import org.hibernate.LockOptions;

20
import org.hibernate.Session;

21
import org.hibernate.criterion.Criterion;

22
import org.hibernate.event.spi.MergeEvent;

23

  
24
import eu.etaxonomy.cdm.api.service.pager.Pager;

25
import eu.etaxonomy.cdm.model.common.ICdmBase;

26
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;

27
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;

28
import eu.etaxonomy.cdm.persistence.dto.MergeResult;

29
import eu.etaxonomy.cdm.persistence.hibernate.PostMergeEntityListener;

30
import eu.etaxonomy.cdm.persistence.query.Grouping;

31
import eu.etaxonomy.cdm.persistence.query.MatchMode;

32
import eu.etaxonomy.cdm.persistence.query.OrderHint;

33
import javassist.tools.rmi.ObjectNotFoundException;
34

  
35
/**

36
 * @author a.kohlbecker

37
 * @since 23.03.2009

38
 *

39
 * @param <T>

40
 */

41
public interface IService<T extends ICdmBase>{
42

  
43
    // FIXME what does this method do?

44
    public void clear();
45

  
46
    /**

47
     * Obtain the specified lock mode on the given object t

48
     * <BR>

49
     * NOTE: with hibernate 4 we changed parameter lockMode to lockOptions. LockOptions can be created from LockMode.

50
     */

51
    public void lock(T t, LockOptions lockOptions);
52

  
53
    /**

54
     * Refreshes a given object t using the specified lockmode

55
     *

56
     * All bean properties given in the <code>propertyPaths</code> parameter are recursively initialized.

57
     * <p>

58
     * For detailed description and examples <b>please refer to:</b>

59
     * {@link IBeanInitializer#initialize(Object, List)}

60
     *

61
     * NOTE: in the case of lockmodes that hit the database (e.g. LockMode.READ), you will need to re-initialize

62
     * child propertiesto avoid a HibernateLazyInitializationException (even if the properties of the child

63
     * were initialized prior to the refresh).

64
     *

65
     * NOTE: with hibernate 4 we changed parameter lockMode to lockOptions. LockOptions can be created from LockMode.

66
     *

67
     * @param t

68
     * @param lockOptions

69
     */

70
    public void refresh(T t, LockOptions lockOptions, List<String> propertyPaths);
71

  
72
    /**

73
     * Returns a count of all entities of type <T>  optionally restricted

74
     * to objects belonging to a class that that extends <T>

75
     *

76
     * @param clazz the class of entities to be counted (can be null to count all entities of type <T>)

77
     * @return a count of entities

78
     */

79
    public int count(Class<? extends T> clazz);
80

  
81
    /**

82
     * Delete an existing persistent object

83
     *

84
     * @param persistentObject the object to be deleted

85
     * @return the unique identifier of the deleted entity

86
     * @return deleteResult

87
     */

88
    public DeleteResult delete(UUID persistentObjectUUID) ;
89

  
90
    /**

91
     * Returns true if an entity of type <T> with a unique identifier matching the

92
     * identifier supplied exists in the database, or false if no such entity can be

93
     * found.

94
     * @param uuid the unique identifier of the entity required

95
     * @return an entity of type <T> matching the uuid, or null if that entity does not exist

96
     */

97
    public boolean exists(UUID uuid);
98

  
99
    /**

100
     * Return a list of persisted entities that match the unique identifier

101
     * set supplied as an argument

102
     *

103
     * @param uuidSet the set of unique identifiers of the entities required

104
     * @return a list of entities of type <T>

105
     */

106
    public List<T> find(Set<UUID> uuidSet);
107

  
108
    /**

109
     * Return a list of persisted entities that match the unique identifier

110
     * set supplied as an argument and that do match the supplied class.

111
     *

112
     * @param uuidSet the set of unique identifiers of the entities required

113
     * @return a list of entities of type <T>

114
     */

115
    public <S extends T> List<S> find(Class<S> clazz, Set<UUID> uuidSet);
116

  
117
    /**

118
     * Return a persisted entity that matches the unique identifier

119
     * supplied as an argument, or null if the entity does not exist

120
     *

121
     * @param uuid the unique identifier of the entity required

122
     * @return an entity of type <T>, or null if the entity does not exist or uuid is <code>null</code>

123
     */

124
    public T find(UUID uuid);
125

  
126
	/**

127
	 * Return a persisted entity that matches the unique identifier

128
     * supplied as an argument, or null if the entity does not exist.

129
     * <p>

130
     * The difference between this method and {@link #find(UUID) find} is

131
     * that this method makes the hibernate read query with the

132
     * {@link org.hibernate.FlushMode FlushMode} for the session set to 'MANUAL'

133
     * <p>

134
     * <b>WARNING:</b>This method should <em>ONLY</em> be used when it is absolutely

135
     * necessary and safe to ensure that the hibernate session is not flushed before a read

136
     * query. A use case for this is the {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase CdmCacher},

137
     * (ticket #4276) where a call to {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase#load(UUID) load}

138
     * the CDM Entity using the standard {@link #find(UUID) find} method results in recursion

139
     * due to the fact that the {@link #find(UUID) find} method triggers a hibernate session

140
     * flush which eventually could call {@link eu.etaxonomy.cdm.model.name.NonViralName#getNameCache getNameCache},

141
	 * which in turn (in the event that name cache is null) eventually calls the

142
	 * {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase#load(UUID uuid) load} again.

143
	 * Apart from these kind of exceptional circumstances, the standard {@link #find(UUID) find}

144
	 * method should always be used to ensure that the persistence layer is always in sync with the

145
	 * underlying database.

146
	 *

147
	 * @param uuid

148
	 * @return an entity of type <T>, or null if the entity does not exist or uuid is <code>null</code>

149
	 */

150
	public T findWithoutFlush(UUID uuid);
151

  
152
    /**

153
     * Return a persisted entity that matches the database identifier

154
     * supplied as an argument, or null if the entity does not exist

155
     *

156
     * @param id the database identifier of the entity required

157
     * @return an entity of type <T>, or null if the entity does not exist

158
     */

159
    public T find(int id);
160

  
161
    /**

162
     * Returns a <code>List</code> of persisted entities that match the database identifiers.

163
     * Returns an empty list if no identifier matches.

164
     *

165
     * @param idSet

166
     * @return

167
     * @deprecated use {@link #loadByIds(Set, List)} instead

168
     */

169
    @Deprecated

170
    public List<T> findById(Set<Integer> idSet);  //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
171

  
172

  
173
    // FIXME should we expose this method?

174
    public Session getSession();
175

  
176
    /**

177
     * Returns a sublist of objects matching the grouping projections supplied using the groups parameter

178
     *

179
     * It would be nice to be able to return a pager, but for the moment hibernate doesn't

180
     * seem to support this (HHH-3238 - impossible to get the rowcount for a criteria that has projections)

181
     *

182
     * @param clazz Restrict the query to objects of a certain class, or null for all objects of type T or subclasses

183
     * @param limit the maximum number of entities returned (can be null to return

184
     *            all entities)

185
     * @param start The (0-based) offset from the start of the recordset (can be null, equivalent of starting at the beginning of the recordset)

186
     * @param groups The grouping objects representing a projection, plus an optional ordering on that projected property

187
     * @param propertyPaths paths initialized on the returned objects - only applied to the objects returned from the first grouping

188
     * @return a list of arrays of objects, each matching the grouping objects supplied in the parameters.

189
     */

190
    public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths);
191

  
192
    /**

193
     * Returns a list of entities of type <T> optionally restricted

194
     * to objects belonging to a class that extends <T>

195
     *

196
     * @param type  The type of entities to return (can be null to count all entities of type <T>)

197
     * @param limit The maximum number of objects returned (can be null for all matching objects)

198
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)

199
     * @param orderHints

200
     *            Supports path like <code>orderHints.propertyNames</code> which

201
     *            include *-to-one properties like createdBy.username or

202
     *            authorTeam.persistentTitleCache

203
     * @param propertyPaths properties to be initialized

204
     * @return

205
     */

206
    //TODO refactor to public <S extends T> List<T> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);

207
    public <S extends T>  List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
208

  
209
    /**

210
     * Finds the cdm entity specified by the <code>uuid</code> parameter and

211
     * initializes all its *ToOne relations.

212
     *

213
     * @param uuid

214
     * @return the cdm entity or <code>null</code> if not object with given uuid exists or uuid is <code>null</code>

215
     */

216
    public T load(UUID uuid);
217

  
218
    /**

219
     * Return a persisted entity that matches the database identifier

220
     * supplied as an argument, or null if the entity does not exist

221
     *

222
     * @param id the database identifier of the entity required

223
     * @param propertyPaths

224
     * @return

225
     */

226
    public T load(int id, List<String> propertyPaths);
227

  
228
    /**

229
     * Returns the object for the given id without initializing it. So the returned

230
     * object usually is a proxy object except for the case when it was already initialized

231
     * before in the same session.<BR>

232
     * This methods wraps {@link Session#load(Class, java.io.Serializable)}.<BR>

233
     * It does not check, if the object really exists but throws an {@link ObjectNotFoundException}

234
     * exception when no record with the given id exists in the database.

235
     * @return

236
     *         the (uninitialized proxy) object

237
     */

238
    public T loadWithoutInitializing(int id);

239

  
240
    /**

241
     * Finds the cdm entity specified by the <code>uuid</code> parameter and

242
     * recursively initializes all bean properties given in the

243
     * <code>propertyPaths</code> parameter.

244
     * <p>

245
     * For detailed description and examples <b>please refer to:</b>

246
     * {@link IBeanInitializer#initialize(Object, List)}

247
     *

248
     * @param uuid

249
     * @return the cdm entity or <code>null</code> if not object with given uuid exists or uuid is <code>null</code>

250
     */

251
    public T load(UUID uuid, List<String> propertyPaths);

252

  
253

  
254
    /**

255
     * Finds the cdm entities specified by the <code>uuids</code>,

256
     * recursively initializes all bean properties given in the

257
     * <code>propertyPaths</code> parameter and returns the initialised

258
     * entity list;

259
     * <p>

260
     * For detailed description and examples <b>please refer to:</b>

261
     * {@link IBeanInitializer#initialize(Object, List)}

262
     * @param uuids

263
     * @param propertyPaths

264
     * @return

265
     */

266
    public List<T> load(List<UUID> uuids, List<String> propertyPaths);

267

  
268
    /**

269
     * Copy the state of the given object onto the persistent object with the same identifier.

270
     *

271
     * @param transientObject the entity to be merged

272
     * @return The unique identifier of the persisted entity

273
     */

274
    public T merge(T transientObject);

275

  
276
    /**

277
     * Returns a paged list of entities of type <T> optionally restricted

278
     * to objects belonging to a class that that extends <T>

279
     *

280
     * @param type  The type of entities to return (can be null to count all entities of type <T>)

281
     * @param pageSize The maximum number of objects returned (can be null for all matching objects)

282
     * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based,

283
     *                   can be null, equivalent of starting at the beginning of the recordset)

284
     * @param orderHints

285
     *            Supports path like <code>orderHints.propertyNames</code> which

286
     *            include *-to-one properties like createdBy.username or

287
     *            authorTeam.persistentTitleCache

288
     * @param propertyPaths properties to be initialized

289
     * @return a pager of objects of type <T>

290
     */

291
    public <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths);

292

  
293
    /**

294
     * Re-read the state of the given instance from the underlying database.

295
     *

296
     * Hibernate claims that it is inadvisable to use refresh in long-running-sessions.

297
     * I don't really see where we would get into a situation where problems as discussed

298
     * this forum thread would apply for our scenario

299
     *

300
     * http://forum.hibernate.org/viewtopic.php?t=974544

301
     *

302
     * @param persistentObject the object to be refreshed

303
     * @return the unique identifier

304
     */

305
    public UUID refresh(T persistentObject);

306

  
307
    /**

308
     * Save a collection containing new entities (persists the entities)

309
     * @param newInstances the new entities to be persisted

310
     * @return A Map containing the new entities, keyed using the generated UUID's

311
     *         of those entities

312
     */

313
    public Map<UUID,T> save(Collection<? extends T> newInstances);

314

  
315
    /**

316
     * Save a new entity (persists the entity)

317
     * @param newInstance the new entity to be persisted

318
     * @return The new persistent entity

319
     */

320
    public <S extends T> S save(S newInstance);

321

  
322
    /**

323
     * Save a new entity or update the persistent state of an existing

324
     * transient entity that has been persisted previously

325
     *

326
     * @param transientObject the entity to be persisted

327
     * @return The unique identifier of the persisted entity

328
     */

329
    public UUID saveOrUpdate(T transientObject);

330

  
331
    /**

332
     * Save new entities or update the persistent state of existing

333
     * transient entities that have been persisted previously

334
     *

335
     * @param transientObjects the entities to be persisted

336
     * @return The unique identifier of the persisted entity

337
     */

338
    public Map<UUID,T> saveOrUpdate(Collection<T> transientObjects);

339

  
340
    /**

341
     * Update the persistent state of an existing transient entity

342
     * that has been persisted previously

343
     *

344
     * @param transientObject the entity to be persisted

345
     * @return The unique identifier of the persisted entity

346
     */

347
    public UUID update(T transientObject);

348

  
349
    /**

350
     * Simply calls the load method.

351
     * Required specifically for the editor to allow load calls which

352
     * can also update the session cache.

353
     *

354
     * @param uuid

355
     * @return

356
     */

357
    public T loadWithUpdate(UUID uuid);

358

  
359
    /**

360
     * Method that lists the objects matching the example provided.

361
     * The includeProperties property is used to specify which properties of the example are used.

362
     *

363
     * If includeProperties is null or empty, then all literal properties are used (restrictions are

364
     * applied as in the Hibernate Query-By-Example API call Example.create(object)).

365
     *

366
     * If includeProperties is not empty then only literal properties that are named in the set are used to

367
     * create restrictions, *PLUS* any *ToOne related entities. Related entities are matched on ID, not by

368
     * their internal literal values (e.g. the call is criteria.add(Restrictions.eq(property,relatedObject)), not

369
     * criteria.createCriteria(property).add(Example.create(relatedObject)))

370
     *

371
     * @param example

372
     * @param includeProperties

373
     * @param limit the maximum number of entities returned (can be null to return

374
     *            all entities)

375
     * @param start The (0-based) offset from the start of the recordset

376
     * @param orderHints

377
     *            Supports path like <code>orderHints.propertyNames</code> which

378
     *            include *-to-one properties like createdBy.username or

379
     * @param propertyPaths paths initialized on the returned objects - only applied to the objects returned from the first grouping

380
     * @return a list of matching objects

381
     */

382
    public <S extends T> List<S> list(S example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);

383

  
384
	public DeleteResult delete(T persistentObject);

385

  
386
    /**

387
     * Deletes a collection of persistent objects correponding to the

388
     * given list of uuids. The result will have status as ok if even one

389
     * of the deletes is successful, else error.

390
     *

391
     * @param persistentObjectUUIDs uuids of persistent objects to delete

392
     * @return DeleteResult object

393
     */

394
    public DeleteResult delete(Collection<UUID> persistentObjectUUIDs);

395

  
396
    /**

397
     * Merges a list of detached objects and returns the new

398
     * list of merged objects

399
     *

400
     * @param detachedObjects

401
     * @return a list of merged objects

402
     */

403
    public List<T> merge(List<T> detachedObjects);

404

  
405
    /**

406
     * Loads a batch of entities referenced by their ids.

407
     *

408
     * @param idSet

409
     * @param propertyPaths

410
     * @return

411
     */

412
    List<T> loadByIds(List<Integer> idSet, List<String> propertyPaths);

413

  
414
    /**

415
     * Loads a batch of entities referenced by their ids.

416
     * @param idSet

417
     * @param orderHints

418
     * @param propertyPaths

419
     * @return

420
     */

421
    List<T> loadByIds(List<Integer> idSet, List<OrderHint> orderHints, List<String> propertyPaths);

422

  
423

  
424
    /**

425
     * This method allows for the possibility of returning the input transient

426
     * entities instead of the merged persistent entity

427
     *

428
     * WARNING : This method should never be used when the objective of the merge

429
     * is to attach to an existing session which is the standard use case.

430
     * This method should only be used in the

431
     * case of an external call which does not use hibernate sessions and is

432
     * only interested in the entity as a POJO. Apart from the session information

433
     * the only other difference between the transient and persisted object is in the case

434
     * of new objects (id=0) where hibernate sets the id after commit. This id is copied

435
     * over to the transient entity in {@link PostMergeEntityListener#onMerge(MergeEvent,Map)}

436
     * making the two objects identical and allowing the transient object to be used further

437
     * as a POJO

438
     *

439
     * @param detachedObjects

440
     * @param returnTransientEntity

441
     * @return

442
     */

443
    public List<MergeResult<T>> merge(List<T> detachedObjects, boolean returnTransientEntity);

444

  
445
    /**

446
     * This method allows for the possibility of returning the input transient

447
     * entity instead of the merged persistent entity

448
     *

449
     * WARNING : This method should never be used when the objective of the merge

450
     * is to attach to an existing session which is the standard use case.

451
     * This method should only be used in the case of an external call which does

452
     * not use hibernate sessions and is only interested in the entity as a POJO.

453
     * This method returns the root merged transient entity as well as all newly merged

454
     * persistent entities within the return object.

455
     *

456
     * @param newInstance

457
     * @param returnTransientEntity

458
     * @return

459
     */

460
    public MergeResult<T> merge(T newInstance, boolean returnTransientEntity);

461

  
462
    public <S extends T> Pager<S> page(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths);

463

  
464
    public <S extends T> Pager<S> pageByParamWithRestrictions(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints,

465
            List<String> propertyPaths);

466

  
467
    public <S extends T> Pager<S> page(Class<S> clazz, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex,

468
            List<OrderHint> orderHints, List<String> propertyPaths);

469

  
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

  
10
package eu.etaxonomy.cdm.api.service;
11

  
12

  
13
import java.util.Collection;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.UUID;
18

  
19
import org.hibernate.LockOptions;
20
import org.hibernate.Session;
21
import org.hibernate.criterion.Criterion;
22
import org.hibernate.event.spi.MergeEvent;
23

  
24
import eu.etaxonomy.cdm.api.service.pager.Pager;
25
import eu.etaxonomy.cdm.model.common.ICdmBase;
26
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
27
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
28
import eu.etaxonomy.cdm.persistence.dto.MergeResult;
29
import eu.etaxonomy.cdm.persistence.hibernate.PostMergeEntityListener;
30
import eu.etaxonomy.cdm.persistence.query.Grouping;
31
import eu.etaxonomy.cdm.persistence.query.MatchMode;
32
import eu.etaxonomy.cdm.persistence.query.OrderHint;
33

  
34
/**
35
 * @author a.kohlbecker
36
 * @since 23.03.2009
37
 *
38
 * @param <T>
39
 */
40
public interface IService<T extends ICdmBase>{
41

  
42
    // FIXME what does this method do?
43
    public void clear();
44

  
45
    /**
46
     * Obtain the specified lock mode on the given object t
47
     * <BR>
48
     * NOTE: with hibernate 4 we changed parameter lockMode to lockOptions. LockOptions can be created from LockMode.
49
     */
50
    public void lock(T t, LockOptions lockOptions);
51

  
52
    /**
53
     * Refreshes a given object t using the specified lockmode
54
     *
55
     * All bean properties given in the <code>propertyPaths</code> parameter are recursively initialized.
56
     * <p>
57
     * For detailed description and examples <b>please refer to:</b>
58
     * {@link IBeanInitializer#initialize(Object, List)}
59
     *
60
     * NOTE: in the case of lockmodes that hit the database (e.g. LockMode.READ), you will need to re-initialize
61
     * child propertiesto avoid a HibernateLazyInitializationException (even if the properties of the child
62
     * were initialized prior to the refresh).
63
     *
64
     * NOTE: with hibernate 4 we changed parameter lockMode to lockOptions. LockOptions can be created from LockMode.
65
     *
66
     * @param t
67
     * @param lockOptions
68
     */
69
    public void refresh(T t, LockOptions lockOptions, List<String> propertyPaths);
70

  
71
    /**
72
     * Returns a count of all entities of type <T>  optionally restricted
73
     * to objects belonging to a class that that extends <T>
74
     *
75
     * @param clazz the class of entities to be counted (can be null to count all entities of type <T>)
76
     * @return a count of entities
77
     */
78
    public int count(Class<? extends T> clazz);
79

  
80
    /**
81
     * Delete an existing persistent object
82
     *
83
     * @param persistentObject the object to be deleted
84
     * @return the unique identifier of the deleted entity
85
     * @return deleteResult
86
     */
87
    public DeleteResult delete(UUID persistentObjectUUID) ;
88

  
89
    /**
90
     * Returns true if an entity of type <T> with a unique identifier matching the
91
     * identifier supplied exists in the database, or false if no such entity can be
92
     * found.
93
     * @param uuid the unique identifier of the entity required
94
     * @return an entity of type <T> matching the uuid, or null if that entity does not exist
95
     */
96
    public boolean exists(UUID uuid);
97

  
98
    /**
99
     * Return a list of persisted entities that match the unique identifier
100
     * set supplied as an argument
101
     *
102
     * @param uuidSet the set of unique identifiers of the entities required
103
     * @return a list of entities of type <T>
104
     */
105
    public List<T> find(Set<UUID> uuidSet);
106

  
107
    /**
108
     * Return a list of persisted entities that match the unique identifier
109
     * set supplied as an argument and that do match the supplied class.
110
     *
111
     * @param uuidSet the set of unique identifiers of the entities required
112
     * @return a list of entities of type <T>
113
     */
114
    public <S extends T> List<S> find(Class<S> clazz, Set<UUID> uuidSet);
115

  
116
    /**
117
     * Return a persisted entity that matches the unique identifier
118
     * supplied as an argument, or null if the entity does not exist
119
     *
120
     * @param uuid the unique identifier of the entity required
121
     * @return an entity of type <T>, or null if the entity does not exist or uuid is <code>null</code>
122
     */
123
    public T find(UUID uuid);
124

  
125
	/**
126
	 * Return a persisted entity that matches the unique identifier
127
     * supplied as an argument, or null if the entity does not exist.
128
     * <p>
129
     * The difference between this method and {@link #find(UUID) find} is
130
     * that this method makes the hibernate read query with the
131
     * {@link org.hibernate.FlushMode FlushMode} for the session set to 'MANUAL'
132
     * <p>
133
     * <b>WARNING:</b>This method should <em>ONLY</em> be used when it is absolutely
134
     * necessary and safe to ensure that the hibernate session is not flushed before a read
135
     * query. A use case for this is the {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase CdmCacher},
136
     * (ticket #4276) where a call to {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase#load(UUID) load}
137
     * the CDM Entity using the standard {@link #find(UUID) find} method results in recursion
138
     * due to the fact that the {@link #find(UUID) find} method triggers a hibernate session
139
     * flush which eventually could call {@link eu.etaxonomy.cdm.model.name.NonViralName#getNameCache getNameCache},
140
	 * which in turn (in the event that name cache is null) eventually calls the
141
	 * {@link eu.etaxonomy.cdm.api.cache.CdmCacherBase#load(UUID uuid) load} again.
142
	 * Apart from these kind of exceptional circumstances, the standard {@link #find(UUID) find}
143
	 * method should always be used to ensure that the persistence layer is always in sync with the
144
	 * underlying database.
145
	 *
146
	 * @param uuid
147
	 * @return an entity of type <T>, or null if the entity does not exist or uuid is <code>null</code>
148
	 */
149
	public T findWithoutFlush(UUID uuid);
150

  
151
    /**
152
     * Return a persisted entity that matches the database identifier
153
     * supplied as an argument, or null if the entity does not exist
154
     *
155
     * @param id the database identifier of the entity required
156
     * @return an entity of type <T>, or null if the entity does not exist
157
     */
158
    public T find(int id);
159

  
160
    /**
161
     * Returns a <code>List</code> of persisted entities that match the database identifiers.
162
     * Returns an empty list if no identifier matches.
163
     *
164
     * @param idSet
165
     * @return
166
     * @deprecated use {@link #loadByIds(Set, List)} instead
167
     */
168
    @Deprecated
169
    public List<T> findById(Set<Integer> idSet);  //can't be called find(Set<Integer>) as this conflicts with find(Set<UUID)
170

  
171

  
172
    // FIXME should we expose this method?
173
    public Session getSession();
174

  
175
    /**
176
     * Returns a sublist of objects matching the grouping projections supplied using the groups parameter
177
     *
178
     * It would be nice to be able to return a pager, but for the moment hibernate doesn't
179
     * seem to support this (HHH-3238 - impossible to get the rowcount for a criteria that has projections)
180
     *
181
     * @param clazz Restrict the query to objects of a certain class, or null for all objects of type T or subclasses
182
     * @param limit the maximum number of entities returned (can be null to return
183
     *            all entities)
184
     * @param start The (0-based) offset from the start of the recordset (can be null, equivalent of starting at the beginning of the recordset)
185
     * @param groups The grouping objects representing a projection, plus an optional ordering on that projected property
186
     * @param propertyPaths paths initialized on the returned objects - only applied to the objects returned from the first grouping
187
     * @return a list of arrays of objects, each matching the grouping objects supplied in the parameters.
188
     */
189
    public List<Object[]> group(Class<? extends T> clazz,Integer limit, Integer start, List<Grouping> groups, List<String> propertyPaths);
190

  
191
    /**
192
     * Returns a list of entities of type <T> optionally restricted
193
     * to objects belonging to a class that extends <T>
194
     *
195
     * @param type  The type of entities to return (can be null to count all entities of type <T>)
196
     * @param limit The maximum number of objects returned (can be null for all matching objects)
197
     * @param start The offset from the start of the result set (0 - based, can be null - equivalent of starting at the beginning of the recordset)
198
     * @param orderHints
199
     *            Supports path like <code>orderHints.propertyNames</code> which
200
     *            include *-to-one properties like createdBy.username or
201
     *            authorTeam.persistentTitleCache
202
     * @param propertyPaths properties to be initialized
203
     * @return
204
     */
205
    //TODO refactor to public <S extends T> List<T> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
206
    public <S extends T>  List<S> list(Class<S> type, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
207

  
208
    /**
209
     * Finds the cdm entity specified by the <code>uuid</code> parameter and
210
     * initializes all its *ToOne relations.
211
     *
212
     * @param uuid
213
     * @return the cdm entity or <code>null</code> if not object with given uuid exists or uuid is <code>null</code>
214
     */
215
    public T load(UUID uuid);
216

  
217
    /**
218
     * Return a persisted entity that matches the database identifier
219
     * supplied as an argument, or null if the entity does not exist
220
     *
221
     * @param id the database identifier of the entity required
222
     * @param propertyPaths
223
     * @return
224
     */
225
    public T load(int id, List<String> propertyPaths);
226

  
227
    /**
228
     * Returns the object for the given id without initializing it. So the returned
229
     * object usually is a proxy object except for the case when it was already initialized
230
     * before in the same session.<BR>
231
     * This methods wraps {@link Session#load(Class, java.io.Serializable)}.<BR>
232
     * It does not check, if the object really exists but throws an
233
     * exception when no record with the given id exists in the database.
234
     *
235
     * @return
236
     *         the (uninitialized proxy) object
237
     */
238
    public T loadWithoutInitializing(int id);
239

  
240
    /**
241
     * Finds the cdm entity specified by the <code>uuid</code> parameter and
242
     * recursively initializes all bean properties given in the
243
     * <code>propertyPaths</code> parameter.
244
     * <p>
245
     * For detailed description and examples <b>please refer to:</b>
246
     * {@link IBeanInitializer#initialize(Object, List)}
247
     *
248
     * @param uuid
249
     * @return the cdm entity or <code>null</code> if not object with given uuid exists or uuid is <code>null</code>
250
     */
251
    public T load(UUID uuid, List<String> propertyPaths);
252

  
253

  
254
    /**
255
     * Finds the cdm entities specified by the <code>uuids</code>,
256
     * recursively initializes all bean properties given in the
257
     * <code>propertyPaths</code> parameter and returns the initialised
258
     * entity list;
259
     * <p>
260
     * For detailed description and examples <b>please refer to:</b>
261
     * {@link IBeanInitializer#initialize(Object, List)}
262
     * @param uuids
263
     * @param propertyPaths
264
     * @return
265
     */
266
    public List<T> load(List<UUID> uuids, List<String> propertyPaths);
267

  
268
    /**
269
     * Copy the state of the given object onto the persistent object with the same identifier.
270
     *
271
     * @param transientObject the entity to be merged
272
     * @return The unique identifier of the persisted entity
273
     */
274
    public T merge(T transientObject);
275

  
276
    /**
277
     * Returns a paged list of entities of type <T> optionally restricted
278
     * to objects belonging to a class that that extends <T>
279
     *
280
     * @param type  The type of entities to return (can be null to count all entities of type <T>)
281
     * @param pageSize The maximum number of objects returned (can be null for all matching objects)
282
     * @param pageNumber The offset (in pageSize chunks) from the start of the result set (0 - based,
283
     *                   can be null, equivalent of starting at the beginning of the recordset)
284
     * @param orderHints
285
     *            Supports path like <code>orderHints.propertyNames</code> which
286
     *            include *-to-one properties like createdBy.username or
287
     *            authorTeam.persistentTitleCache
288
     * @param propertyPaths properties to be initialized
289
     * @return a pager of objects of type <T>
290
     */
291
    public <S extends T> Pager<S> page(Class<S> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths);
292

  
293
    /**
294
     * Re-read the state of the given instance from the underlying database.
295
     *
296
     * Hibernate claims that it is inadvisable to use refresh in long-running-sessions.
297
     * I don't really see where we would get into a situation where problems as discussed
298
     * this forum thread would apply for our scenario
299
     *
300
     * http://forum.hibernate.org/viewtopic.php?t=974544
301
     *
302
     * @param persistentObject the object to be refreshed
303
     * @return the unique identifier
304
     */
305
    public UUID refresh(T persistentObject);
306

  
307
    /**
308
     * Save a collection containing new entities (persists the entities)
309
     * @param newInstances the new entities to be persisted
310
     * @return A Map containing the new entities, keyed using the generated UUID's
311
     *         of those entities
312
     */
313
    public Map<UUID,T> save(Collection<? extends T> newInstances);
314

  
315
    /**
316
     * Save a new entity (persists the entity)
317
     * @param newInstance the new entity to be persisted
318
     * @return The new persistent entity
319
     */
320
    public <S extends T> S save(S newInstance);
321

  
322
    /**
323
     * Save a new entity or update the persistent state of an existing
324
     * transient entity that has been persisted previously
325
     *
326
     * @param transientObject the entity to be persisted
327
     * @return The unique identifier of the persisted entity
328
     */
329
    public UUID saveOrUpdate(T transientObject);
330

  
331
    /**
332
     * Save new entities or update the persistent state of existing
333
     * transient entities that have been persisted previously
334
     *
335
     * @param transientObjects the entities to be persisted
336
     * @return The unique identifier of the persisted entity
337
     */
338
    public Map<UUID,T> saveOrUpdate(Collection<T> transientObjects);
339

  
340
    /**
341
     * Update the persistent state of an existing transient entity
342
     * that has been persisted previously
343
     *
344
     * @param transientObject the entity to be persisted
345
     * @return The unique identifier of the persisted entity
346
     */
347
    public UUID update(T transientObject);
348

  
349
    /**
350
     * Simply calls the load method.
351
     * Required specifically for the editor to allow load calls which
352
     * can also update the session cache.
353
     *
354
     * @param uuid
355
     * @return
356
     */
357
    public T loadWithUpdate(UUID uuid);
358

  
359
    /**
360
     * Method that lists the objects matching the example provided.
361
     * The includeProperties property is used to specify which properties of the example are used.
362
     *
363
     * If includeProperties is null or empty, then all literal properties are used (restrictions are
364
     * applied as in the Hibernate Query-By-Example API call Example.create(object)).
365
     *
366
     * If includeProperties is not empty then only literal properties that are named in the set are used to
367
     * create restrictions, *PLUS* any *ToOne related entities. Related entities are matched on ID, not by
368
     * their internal literal values (e.g. the call is criteria.add(Restrictions.eq(property,relatedObject)), not
369
     * criteria.createCriteria(property).add(Example.create(relatedObject)))
370
     *
371
     * @param example
372
     * @param includeProperties
373
     * @param limit the maximum number of entities returned (can be null to return
374
     *            all entities)
375
     * @param start The (0-based) offset from the start of the recordset
376
     * @param orderHints
377
     *            Supports path like <code>orderHints.propertyNames</code> which
378
     *            include *-to-one properties like createdBy.username or
379
     * @param propertyPaths paths initialized on the returned objects - only applied to the objects returned from the first grouping
380
     * @return a list of matching objects
381
     */
382
    public <S extends T> List<S> list(S example, Set<String> includeProperties, Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths);
383

  
384
	public DeleteResult delete(T persistentObject);
385

  
386
    /**
387
     * Deletes a collection of persistent objects correponding to the
388
     * given list of uuids. The result will have status as ok if even one
389
     * of the deletes is successful, else error.
390
     *
391
     * @param persistentObjectUUIDs uuids of persistent objects to delete
392
     * @return DeleteResult object
393
     */
394
    public DeleteResult delete(Collection<UUID> persistentObjectUUIDs);
395

  
396
    /**
397
     * Merges a list of detached objects and returns the new
398
     * list of merged objects
399
     *
400
     * @param detachedObjects
401
     * @return a list of merged objects
402
     */
403
    public List<T> merge(List<T> detachedObjects);
404

  
405
    /**
406
     * Loads a batch of entities referenced by their ids.
407
     *
408
     * @param idSet
409
     * @param propertyPaths
410
     * @return
411
     */
412
    List<T> loadByIds(List<Integer> idSet, List<String> propertyPaths);
413

  
414
    /**
415
     * Loads a batch of entities referenced by their ids.
416
     * @param idSet
417
     * @param orderHints
418
     * @param propertyPaths
419
     * @return
420
     */
421
    List<T> loadByIds(List<Integer> idSet, List<OrderHint> orderHints, List<String> propertyPaths);
422

  
423

  
424
    /**
425
     * This method allows for the possibility of returning the input transient
426
     * entities instead of the merged persistent entity
427
     *
428
     * WARNING : This method should never be used when the objective of the merge
429
     * is to attach to an existing session which is the standard use case.
430
     * This method should only be used in the
431
     * case of an external call which does not use hibernate sessions and is
432
     * only interested in the entity as a POJO. Apart from the session information
433
     * the only other difference between the transient and persisted object is in the case
434
     * of new objects (id=0) where hibernate sets the id after commit. This id is copied
435
     * over to the transient entity in {@link PostMergeEntityListener#onMerge(MergeEvent,Map)}
436
     * making the two objects identical and allowing the transient object to be used further
437
     * as a POJO
438
     *
439
     * @param detachedObjects
440
     * @param returnTransientEntity
441
     * @return
442
     */
443
    public List<MergeResult<T>> merge(List<T> detachedObjects, boolean returnTransientEntity);
444

  
445
    /**
446
     * This method allows for the possibility of returning the input transient
447
     * entity instead of the merged persistent entity
448
     *
449
     * WARNING : This method should never be used when the objective of the merge
450
     * is to attach to an existing session which is the standard use case.
451
     * This method should only be used in the case of an external call which does
452
     * not use hibernate sessions and is only interested in the entity as a POJO.
453
     * This method returns the root merged transient entity as well as all newly merged
454
     * persistent entities within the return object.
455
     *
456
     * @param newInstance
457
     * @param returnTransientEntity
458
     * @return
459
     */
460
    public MergeResult<T> merge(T newInstance, boolean returnTransientEntity);
461

  
462
    public <S extends T> Pager<S> page(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints, List<String> propertyPaths);
463

  
464
    public <S extends T> Pager<S> pageByParamWithRestrictions(Class<S> clazz, String param, String queryString, MatchMode matchmode, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex, List<OrderHint> orderHints,
465
            List<String> propertyPaths);
466

  
467
    public <S extends T> Pager<S> page(Class<S> clazz, List<Restriction<?>> restrictions, Integer pageSize, Integer pageIndex,
468
            List<OrderHint> orderHints, List<String> propertyPaths);
469

  
470 470
}
cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/facade/DerivedUnitFacadeCacheStrategyInjectionTest.java
216 216
        Assert.assertEquals(correctCache, fieldUnit.getTitleCache());
217 217
    }
218 218

  
219
    //Test if even a hibernate proxy (javassist) class correctly loads the DerivedUnitCacheStrategy.
219
    //Test if even a hibernate proxy class correctly loads the DerivedUnitCacheStrategy.
220 220
    @Test
221 221
    @DataSet
222 222
    public void testPersistedDerivedUnit(){
cdmlib-test/src/main/resources/eu/etaxonomy/cdm/applicationContext-test.common.xml
62 62
                      locks must not only be released after application shutdown in test environment -->
63 63
                <prop key="hibernate.search.default.exclusive_index_use">false</prop>
64 64
                <prop key="hibernate.dialect">org.hibernate.dialect.H2CorrectedDialectTest</prop>
65
                <prop key="hibernate.bytecode.provider">javassist</prop>                
66 65
                <prop key="implicitNamingStrategy">org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl"</prop>
67 66
            </props>
68 67
        </property>
cdmlib-test/src/test/resources/eu/etaxonomy/cdm/hibernate.cfg.xml
7 7
    <session-factory>
8 8

  
9 9
      <property name="connection.release_mode">after_transaction</property>
10
      
11
      <property name="hibernate.bytecode.provider">javassist</property>
12 10

  
13 11
      <!-- Connection Pooling -->
14 12
<!--       <property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> -->
pom.xml
1387 1387
        <version>${hibernate-search.version}</version>
1388 1388
      </dependency>
1389 1389
      <dependency>
1390
        <!-- TODO can be removed when upgraded to bytebuddy, not used anymore by hibernate, but still a dependency in 5.4.x -->
1391
        <groupId>org.javassist</groupId>
1392
        <artifactId>javassist</artifactId>
1393
        <version>3.29.0-GA</version>
1394
      </dependency>
1395
      <dependency>
1396
        <!-- TODO not yet required as we still use javassist -->
1390
        <!-- used by hibernate as bytecode provider framework -->
1397 1391
        <groupId>net.bytebuddy</groupId>
1398 1392
        <artifactId>byte-buddy</artifactId>
1399 1393
        <version>1.12.10</version>

Also available in: Unified diff