or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

exception-handling.mdhibernate-integration.mdindex.mdjpa-integration.mdpersistence-context.mdtransaction-management.md

jpa-integration.mddocs/

0

# JPA Integration

1

2

Spring ORM provides comprehensive integration with the Java Persistence API (JPA), offering EntityManagerFactory configuration, transaction management, shared EntityManager creation, vendor-specific adaptations, and annotation-driven dependency injection. This integration supports both container-managed and application-managed persistence contexts with full Spring lifecycle management.

3

4

## Capabilities

5

6

### EntityManagerFactory Configuration

7

8

Configure JPA EntityManagerFactory instances with Spring lifecycle management, automatic entity scanning, vendor-specific properties, and DataSource integration.

9

10

```java { .api }

11

public abstract class AbstractEntityManagerFactoryBean implements FactoryBean<EntityManagerFactory>,

12

BeanClassLoaderAware, BeanNameAware, InitializingBean, DisposableBean, EntityManagerFactoryInfo, Serializable {

13

public void setJpaVendorAdapter(JpaVendorAdapter jpaVendorAdapter);

14

public JpaVendorAdapter getJpaVendorAdapter();

15

public void setPersistenceProvider(PersistenceProvider persistenceProvider);

16

public void setJpaProperties(Properties jpaProperties);

17

public void setEntityManagerInitializer(Consumer<EntityManager> entityManagerInitializer);

18

public abstract EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException;

19

}

20

21

public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean

22

implements ResourceLoaderAware, LoadTimeWeaverAware {

23

public void setPersistenceUnitManager(PersistenceUnitManager persistenceUnitManager);

24

public void setPersistenceXmlLocation(String persistenceXmlLocation);

25

public void setManagedTypes(PersistenceManagedTypes managedTypes);

26

public void setPackagesToScan(String... packagesToScan);

27

public void setMappingResources(String... mappingResources);

28

public void setDataSource(DataSource dataSource);

29

public void setJtaDataSource(DataSource jtaDataSource);

30

public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver);

31

public EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException;

32

}

33

34

public class LocalEntityManagerFactoryBean extends AbstractEntityManagerFactoryBean {

35

public void setDataSource(DataSource dataSource);

36

public DataSource getDataSource();

37

38

protected EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException;

39

}

40

```

41

42

#### Usage Example

43

44

```java

45

@Configuration

46

@EnableJpaRepositories

47

public class JpaConfig {

48

49

@Bean

50

public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

51

LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();

52

em.setDataSource(dataSource());

53

em.setPackagesToScan("com.example.entity");

54

em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

55

56

Properties jpaProperties = new Properties();

57

jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");

58

jpaProperties.setProperty("hibernate.hbm2ddl.auto", "validate");

59

jpaProperties.setProperty("hibernate.show_sql", "false");

60

em.setJpaProperties(jpaProperties);

61

62

// Custom EntityManager initialization

63

em.setEntityManagerInitializer(entityManager -> {

64

entityManager.setProperty("hibernate.jdbc.batch_size", 20);

65

});

66

67

return em;

68

}

69

70

@Bean

71

public DataSource dataSource() {

72

HikariDataSource dataSource = new HikariDataSource();

73

dataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");

74

dataSource.setUsername("user");

75

dataSource.setPassword("password");

76

return dataSource;

77

}

78

}

79

```

80

81

### JPA Transaction Management

82

83

Dedicated transaction management for JPA with EntityManager lifecycle integration, resource synchronization, and transaction-aware EntityManager creation.

84

85

```java { .api }

86

public class JpaTransactionManager extends AbstractPlatformTransactionManager

87

implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {

88

public JpaTransactionManager();

89

public JpaTransactionManager(EntityManagerFactory emf);

90

public void setEntityManagerFactory(EntityManagerFactory emf);

91

public EntityManagerFactory getEntityManagerFactory();

92

public void setPersistenceUnitName(String persistenceUnitName);

93

public void setJpaProperties(Properties jpaProperties);

94

public void setDataSource(DataSource dataSource);

95

public void setJpaDialect(JpaDialect jpaDialect);

96

public void setEntityManagerInitializer(Consumer<EntityManager> entityManagerInitializer);

97

}

98

99

public abstract class EntityManagerFactoryAccessor implements BeanFactoryAware {

100

public void setEntityManagerFactory(EntityManagerFactory emf);

101

public EntityManagerFactory getEntityManagerFactory();

102

public EntityManagerFactory obtainEntityManagerFactory();

103

}

104

```

105

106

#### Usage Example

107

108

```java

109

@Configuration

110

@EnableTransactionManagement

111

public class TransactionConfig {

112

113

@Bean

114

public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {

115

JpaTransactionManager txManager = new JpaTransactionManager();

116

txManager.setEntityManagerFactory(entityManagerFactory);

117

118

// Optional: Set DataSource for connection-level transaction synchronization

119

txManager.setDataSource(dataSource());

120

121

// Optional: Custom JPA dialect for vendor-specific behavior

122

txManager.setJpaDialect(new HibernateJpaDialect());

123

124

return txManager;

125

}

126

}

127

128

@Service

129

@Transactional

130

public class UserService {

131

132

@PersistenceContext

133

private EntityManager entityManager;

134

135

public void createUser(String name, String email) {

136

User user = new User();

137

user.setName(name);

138

user.setEmail(email);

139

entityManager.persist(user);

140

// Transaction automatically commits on method completion

141

}

142

143

@Transactional(readOnly = true)

144

public User findUser(Long id) {

145

return entityManager.find(User.class, id);

146

}

147

}

148

```

149

150

### Shared EntityManager Creation

151

152

Create thread-safe EntityManager proxies that automatically participate in Spring-managed transactions and handle proper resource lifecycle.

153

154

```java { .api }

155

public abstract class SharedEntityManagerCreator {

156

public static EntityManager createSharedEntityManager(EntityManagerFactory emf);

157

public static EntityManager createSharedEntityManager(EntityManagerFactory emf, Map<?, ?> properties);

158

public static EntityManager createSharedEntityManager(EntityManagerFactory emf, Map<?, ?> properties, boolean synchronizedWithTransaction);

159

public static EntityManager createSharedEntityManager(EntityManagerFactory emf, Map<?, ?> properties, Class<?>... entityManagerInterfaces);

160

public static EntityManager createSharedEntityManager(EntityManagerFactory emf, Map<?, ?> properties, boolean synchronizedWithTransaction, Class<?>... entityManagerInterfaces);

161

}

162

163

public class SharedEntityManagerBean extends EntityManagerFactoryAccessor

164

implements FactoryBean<EntityManager>, InitializingBean {

165

public void setPersistenceUnitName(String persistenceUnitName);

166

public void setJpaProperties(Properties jpaProperties);

167

public EntityManager getObject();

168

public Class<? extends EntityManager> getObjectType();

169

}

170

```

171

172

#### Usage Example

173

174

```java

175

@Configuration

176

public class EntityManagerConfig {

177

178

@Bean

179

public EntityManager sharedEntityManager(EntityManagerFactory entityManagerFactory) {

180

Map<String, Object> properties = new HashMap<>();

181

properties.put("hibernate.jdbc.batch_size", 25);

182

properties.put("hibernate.order_inserts", true);

183

184

return SharedEntityManagerCreator.createSharedEntityManager(

185

entityManagerFactory,

186

properties

187

);

188

}

189

}

190

191

@Repository

192

public class ProductRepository {

193

194

@Autowired

195

private EntityManager entityManager; // Shared EntityManager

196

197

@Transactional

198

public void saveProducts(List<Product> products) {

199

for (int i = 0; i < products.size(); i++) {

200

entityManager.persist(products.get(i));

201

if (i % 25 == 0) {

202

entityManager.flush();

203

entityManager.clear();

204

}

205

}

206

}

207

}

208

```

209

210

### JPA Vendor Adapters

211

212

Vendor-specific implementations providing optimal integration with different JPA providers including Hibernate and EclipseLink.

213

214

```java { .api }

215

public interface JpaVendorAdapter {

216

PersistenceProvider getPersistenceProvider();

217

String getPersistenceProviderRootPackage();

218

Map<String, ?> getJpaPropertyMap(PersistenceUnitInfo pui);

219

JpaDialect getJpaDialect();

220

Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface();

221

void postProcessEntityManagerFactory(EntityManagerFactory emf);

222

}

223

224

public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {

225

public void setDatabase(Database database);

226

public Database getDatabase();

227

public void setDatabasePlatform(String databasePlatform);

228

public void setGenerateDdl(boolean generateDdl);

229

public void setShowSql(boolean showSql);

230

}

231

232

public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {

233

public void setPrepareConnection(boolean prepareConnection);

234

public PersistenceProvider getPersistenceProvider();

235

public String getPersistenceProviderRootPackage();

236

public Map<String, Object> getJpaPropertyMap(PersistenceUnitInfo pui);

237

public Map<String, Object> getJpaPropertyMap();

238

public HibernateJpaDialect getJpaDialect();

239

public Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface();

240

public Class<? extends EntityManager> getEntityManagerInterface();

241

242

protected Class<?> determineDatabaseDialectClass(Database database);

243

}

244

245

public class EclipseLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {

246

public PersistenceProvider getPersistenceProvider();

247

public Map<String, Object> getJpaPropertyMap();

248

public EclipseLinkJpaDialect getJpaDialect();

249

public Class<? extends EntityManager> getEntityManagerInterface();

250

251

protected String determineTargetDatabaseName(Database database);

252

}

253

254

public enum Database {

255

DEFAULT, DB2, DERBY, H2, HANA, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE

256

}

257

```

258

259

#### Usage Example

260

261

```java

262

@Configuration

263

public class VendorConfig {

264

265

@Bean

266

public JpaVendorAdapter hibernateVendorAdapter() {

267

HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();

268

adapter.setDatabase(Database.POSTGRESQL);

269

adapter.setGenerateDdl(false);

270

adapter.setShowSql(true);

271

adapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQL95Dialect");

272

return adapter;

273

}

274

275

@Bean

276

public JpaVendorAdapter eclipseLinkVendorAdapter() {

277

EclipseLinkJpaVendorAdapter adapter = new EclipseLinkJpaVendorAdapter();

278

adapter.setDatabase(Database.MYSQL);

279

adapter.setGenerateDdl(true);

280

adapter.setShowSql(false);

281

return adapter;

282

}

283

}

284

```

285

286

### JPA Dialects

287

288

Vendor-specific dialect implementations that provide access to advanced features like JDBC connections and transaction customization.

289

290

```java { .api }

291

public interface JpaDialect extends PersistenceExceptionTranslator {

292

Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException;

293

Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name) throws PersistenceException;

294

void cleanupTransaction(Object transactionData);

295

ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;

296

void releaseJdbcConnection(ConnectionHandle conHandle, EntityManager entityManager) throws PersistenceException, SQLException;

297

}

298

299

public class DefaultJpaDialect implements JpaDialect, Serializable {

300

public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException;

301

public Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name) throws PersistenceException;

302

public void cleanupTransaction(Object transactionData);

303

public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;

304

public void releaseJdbcConnection(ConnectionHandle conHandle, EntityManager entityManager) throws PersistenceException, SQLException;

305

public DataAccessException translateExceptionIfPossible(RuntimeException ex);

306

}

307

308

public class HibernateJpaDialect extends DefaultJpaDialect {

309

public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException;

310

public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException;

311

public DataAccessException translateExceptionIfPossible(RuntimeException ex);

312

}

313

314

public class EclipseLinkJpaDialect extends DefaultJpaDialect {

315

// EclipseLink-specific implementations

316

}

317

```

318

319

### EntityManager Utilities

320

321

Helper utilities for obtaining transactional EntityManager instances, applying transaction timeouts, and converting JPA exceptions.

322

323

```java { .api }

324

public abstract class EntityManagerFactoryUtils {

325

public static final int ENTITY_MANAGER_SYNCHRONIZATION_ORDER = DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER + 100;

326

327

public static EntityManager getTransactionalEntityManager(EntityManagerFactory emf) throws DataAccessException;

328

public static EntityManager getTransactionalEntityManager(EntityManagerFactory emf, Map<?, ?> properties) throws DataAccessException;

329

public static EntityManager doGetTransactionalEntityManager(EntityManagerFactory emf, Map<?, ?> properties) throws DataAccessException;

330

public static void applyTransactionTimeout(Query query, EntityManagerFactory emf);

331

public static DataAccessException convertJpaAccessExceptionIfPossible(RuntimeException ex);

332

public static void closeEntityManager(EntityManager em);

333

}

334

335

public class EntityManagerHolder extends ResourceHolderSupport {

336

public EntityManagerHolder(EntityManager entityManager);

337

public EntityManager getEntityManager();

338

public void setTransactionActive(boolean transactionActive);

339

public boolean isTransactionActive();

340

}

341

```

342

343

#### Usage Example

344

345

```java

346

@Component

347

public class CustomDataAccess {

348

349

@Autowired

350

private EntityManagerFactory entityManagerFactory;

351

352

public void performCustomOperation() {

353

EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);

354

try {

355

Query query = em.createQuery("SELECT u FROM User u WHERE u.active = true");

356

EntityManagerFactoryUtils.applyTransactionTimeout(query, entityManagerFactory);

357

358

@SuppressWarnings("unchecked")

359

List<User> users = query.getResultList();

360

361

// Process users...

362

363

} catch (RuntimeException ex) {

364

DataAccessException dae = EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);

365

if (dae != null) {

366

throw dae;

367

}

368

throw ex;

369

}

370

}

371

}

372

```

373

374

### Extended EntityManager Support

375

376

Support for both application-managed and container-managed EntityManager patterns with proper lifecycle management.

377

378

```java { .api }

379

public abstract class ExtendedEntityManagerCreator {

380

public static EntityManager createApplicationManagedEntityManager(EntityManager rawEntityManager, EntityManagerFactoryInfo emfInfo);

381

public static EntityManager createContainerManagedEntityManager(EntityManagerFactory emf, Map<?, ?> properties, boolean synchronizedWithTransaction);

382

}

383

384

public interface EntityManagerProxy extends EntityManager {

385

EntityManager getTargetEntityManager();

386

}

387

388

public interface EntityManagerFactoryInfo {

389

PersistenceUnitInfo getPersistenceUnitInfo();

390

String getPersistenceUnitName();

391

DataSource getDataSource();

392

JpaDialect getJpaDialect();

393

EntityManager createNativeEntityManager(Map<String, Object> properties);

394

}

395

```

396

397

### JPA Exception Handling

398

399

JPA-specific exception classes that extend Spring's DataAccessException hierarchy for consistent error handling.

400

401

```java { .api }

402

public class JpaObjectRetrievalFailureException extends ObjectRetrievalFailureException {

403

public JpaObjectRetrievalFailureException(EntityNotFoundException ex);

404

}

405

406

public class JpaOptimisticLockingFailureException extends ObjectOptimisticLockingFailureException {

407

public JpaOptimisticLockingFailureException(OptimisticLockException ex);

408

}

409

410

public class JpaSystemException extends UncategorizedDataAccessException {

411

public JpaSystemException(PersistenceException ex);

412

}

413

```

414

415

## Web Integration Support

416

417

JPA-specific web integration components for managing persistence contexts across HTTP requests.

418

419

```java { .api }

420

public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {

421

public static final String DEFAULT_ENTITY_MANAGER_FACTORY_BEAN_NAME = "entityManagerFactory";

422

423

public void setEntityManagerFactoryBeanName(String entityManagerFactoryBeanName);

424

public String getEntityManagerFactoryBeanName();

425

public void setPersistenceUnitName(String persistenceUnitName);

426

}

427

428

public class OpenEntityManagerInViewInterceptor extends EntityManagerFactoryAccessor

429

implements AsyncWebRequestInterceptor {

430

public static final String PARTICIPATE_SUFFIX = ".PARTICIPATE";

431

432

public void preHandle(WebRequest request) throws DataAccessException;

433

public void postHandle(WebRequest request, ModelMap model);

434

public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException;

435

}

436

```

437

438

#### Usage Example

439

440

```java

441

@Configuration

442

public class WebConfig implements WebMvcConfigurer {

443

444

@Override

445

public void addInterceptors(InterceptorRegistry registry) {

446

OpenEntityManagerInViewInterceptor interceptor = new OpenEntityManagerInViewInterceptor();

447

interceptor.setEntityManagerFactory(entityManagerFactory);

448

registry.addWebRequestInterceptor(interceptor);

449

}

450

}

451

452

// Or as a Servlet Filter

453

@WebFilter("/*")

454

public class CustomOpenEntityManagerInViewFilter extends OpenEntityManagerInViewFilter {

455

456

@Override

457

public void initFilterBean() {

458

setEntityManagerFactoryBeanName("customEntityManagerFactory");

459

setPersistenceUnitName("customPU");

460

}

461

}

462

```

463

464

## Types

465

466

```java { .api }

467

import jakarta.persistence.EntityManager;

468

import jakarta.persistence.EntityManagerFactory;

469

import jakarta.persistence.PersistenceException;

470

import jakarta.persistence.Query;

471

import jakarta.persistence.EntityNotFoundException;

472

import jakarta.persistence.OptimisticLockException;

473

import jakarta.persistence.spi.PersistenceProvider;

474

import jakarta.persistence.spi.PersistenceUnitInfo;

475

import javax.sql.DataSource;

476

import java.util.Map;

477

import java.util.Properties;

478

import java.util.function.Consumer;

479

import org.springframework.transaction.TransactionDefinition;

480

import org.springframework.transaction.PlatformTransactionManager;

481

import org.springframework.dao.DataAccessException;

482

import org.springframework.jdbc.datasource.ConnectionHandle;

483

import org.springframework.orm.jpa.vendor.Database;

484

```