Polishing
This commit is contained in:
parent
bddd3feb83
commit
75f5dac16b
|
@ -281,8 +281,8 @@ Spring Data JPA, make sure to set up deferred bootstrapping for its repositories
|
|||
[[orm-jpa-dao]]
|
||||
== Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager`
|
||||
|
||||
NOTE: Although `EntityManagerFactory` instances are thread-safe, `EntityManager` instances are
|
||||
not. The injected JPA `EntityManager` behaves like an `EntityManager` fetched from an
|
||||
NOTE: Although `EntityManagerFactory` instances are thread-safe, `EntityManager` instances
|
||||
are not. The injected JPA `EntityManager` behaves like an `EntityManager` fetched from an
|
||||
application server's JNDI environment, as defined by the JPA specification. It delegates
|
||||
all calls to the current transactional `EntityManager`, if any. Otherwise, it falls back
|
||||
to a newly created `EntityManager` per operation, in effect making its usage thread-safe.
|
||||
|
@ -290,8 +290,8 @@ to a newly created `EntityManager` per operation, in effect making its usage thr
|
|||
It is possible to write code against the plain JPA without any Spring dependencies, by
|
||||
using an injected `EntityManagerFactory` or `EntityManager`. Spring can understand the
|
||||
`@PersistenceUnit` and `@PersistenceContext` annotations both at the field and the method level
|
||||
if a `PersistenceAnnotationBeanPostProcessor` is enabled. The following example shows a plain JPA DAO implementation
|
||||
that uses the `@PersistenceUnit` annotation:
|
||||
if a `PersistenceAnnotationBeanPostProcessor` is enabled. The following example shows a plain
|
||||
JPA DAO implementation that uses the `@PersistenceUnit` annotation:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
@ -384,9 +384,9 @@ Consider the following example:
|
|||
----
|
||||
|
||||
The main problem with such a DAO is that it always creates a new `EntityManager` through
|
||||
the factory. You can avoid this by requesting a transactional `EntityManager` (also
|
||||
called a "`shared EntityManager`" because it is a shared, thread-safe proxy for the actual
|
||||
transactional EntityManager) to be injected instead of the factory. The following example shows how to do so:
|
||||
the factory. You can avoid this by requesting a transactional `EntityManager` (also called a
|
||||
"`shared EntityManager`" because it is a shared, thread-safe proxy for the actual transactional
|
||||
EntityManager) to be injected instead of the factory. The following example shows how to do so:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
|
@ -430,19 +430,19 @@ The `@PersistenceContext` annotation has an optional attribute called `type`, wh
|
|||
`EntityManager` proxy. The alternative, `PersistenceContextType.EXTENDED`, is a completely
|
||||
different affair. This results in a so-called extended `EntityManager`, which is not
|
||||
thread-safe and, hence, must not be used in a concurrently accessed component, such as a
|
||||
Spring-managed singleton bean. Extended `EntityManager` instances are only supposed to be used in
|
||||
stateful components that, for example, reside in a session, with the lifecycle of the
|
||||
Spring-managed singleton bean. Extended `EntityManager` instances are only supposed to be used#
|
||||
in stateful components that, for example, reside in a session, with the lifecycle of the
|
||||
`EntityManager` not tied to a current transaction but rather being completely up to the
|
||||
application.
|
||||
|
||||
.Method- and field-level Injection
|
||||
****
|
||||
You can apply annotations that indicate dependency injections (such as `@PersistenceUnit` and
|
||||
`@PersistenceContext`) on field or methods inside a class -- hence the
|
||||
expressions "`method-level injection`" and "`field-level injection`". Field-level
|
||||
annotations are concise and easier to use while method-level annotations allow for further
|
||||
processing of the injected dependency. In both cases, the member visibility (public,
|
||||
protected, or private) does not matter.
|
||||
`@PersistenceContext`) on field or methods inside a class -- hence the expressions
|
||||
"`method-level injection`" and "`field-level injection`". Field-level annotations are
|
||||
concise and easier to use while method-level annotations allow for further processing of the
|
||||
injected dependency. In both cases, the member visibility (public, protected, or private)
|
||||
does not matter.
|
||||
|
||||
What about class-level annotations?
|
||||
|
||||
|
@ -451,9 +451,9 @@ injection.
|
|||
****
|
||||
|
||||
The injected `EntityManager` is Spring-managed (aware of the ongoing transaction).
|
||||
Even though the new DAO implementation uses method-level
|
||||
injection of an `EntityManager` instead of an `EntityManagerFactory`, no change is
|
||||
required in the application context XML, due to annotation usage.
|
||||
Even though the new DAO implementation uses method-level injection of an `EntityManager`
|
||||
instead of an `EntityManagerFactory`, no change is required in the bean definition
|
||||
due to annotation usage.
|
||||
|
||||
The main advantage of this DAO style is that it depends only on the Java Persistence API.
|
||||
No import of any Spring class is required. Moreover, as the JPA annotations are understood,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -205,8 +205,7 @@ public class GenericConversionService implements ConfigurableConversionService {
|
|||
* @param targetType the target type
|
||||
* @return the converted value
|
||||
* @throws ConversionException if a conversion exception occurred
|
||||
* @throws IllegalArgumentException if targetType is {@code null},
|
||||
* or sourceType is {@code null} but source is not {@code null}
|
||||
* @throws IllegalArgumentException if targetType is {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
public Object convert(@Nullable Object source, TypeDescriptor targetType) {
|
||||
|
|
|
@ -659,7 +659,7 @@ class DefaultConversionServiceTests {
|
|||
foo.add("2");
|
||||
foo.add("3");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Integer> bar = (List<Integer>) conversionService.convert(foo, TypeDescriptor.forObject(foo),
|
||||
List<Integer> bar = (List<Integer>) conversionService.convert(foo,
|
||||
new TypeDescriptor(getClass().getField("genericList")));
|
||||
assertThat(bar).containsExactly(1, 2, 3);
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ class CollectionToCollectionConverterTests {
|
|||
@Test
|
||||
void listToCollectionNoCopyRequired() throws NoSuchFieldException {
|
||||
List<?> input = new ArrayList<>(Arrays.asList("foo", "bar"));
|
||||
assertThat(conversionService.convert(input, TypeDescriptor.forObject(input),
|
||||
assertThat(conversionService.convert(input,
|
||||
new TypeDescriptor(getClass().getField("wildcardCollection")))).isSameAs(input);
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ class CollectionToCollectionConverterTests {
|
|||
List<String> list = new ArrayList<>();
|
||||
list.add("A");
|
||||
list.add("C");
|
||||
assertThat(conversionService.convert(list, TypeDescriptor.forObject(list), new TypeDescriptor(getClass().getField("enumSet")))).isEqualTo(EnumSet.of(MyEnum.A, MyEnum.C));
|
||||
assertThat(conversionService.convert(list, new TypeDescriptor(getClass().getField("enumSet")))).isEqualTo(EnumSet.of(MyEnum.A, MyEnum.C));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ class GenericConversionServiceTests {
|
|||
void wildcardMap() throws Exception {
|
||||
Map<String, String> input = new LinkedHashMap<>();
|
||||
input.put("key", "value");
|
||||
Object converted = conversionService.convert(input, TypeDescriptor.forObject(input), new TypeDescriptor(getClass().getField("wildcardMap")));
|
||||
Object converted = conversionService.convert(input, new TypeDescriptor(getClass().getField("wildcardMap")));
|
||||
assertThat(converted).isEqualTo(input);
|
||||
}
|
||||
|
||||
|
|
|
@ -417,9 +417,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
logger.debug("Executing SQL statement [" + sql + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to execute the statement.
|
||||
*/
|
||||
// Callback to execute the statement.
|
||||
class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -445,9 +443,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
logger.debug("Executing SQL query [" + sql + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to execute the query.
|
||||
*/
|
||||
// Callback to execute the query.
|
||||
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -542,9 +538,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
logger.debug("Executing SQL update [" + sql + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to execute the update statement.
|
||||
*/
|
||||
// Callback to execute the update statement.
|
||||
class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
|
||||
@Override
|
||||
public Integer doInStatement(Statement stmt) throws SQLException {
|
||||
|
@ -570,9 +564,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
logger.debug("Executing SQL batch update of " + sql.length + " statements");
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to execute the batch update.
|
||||
*/
|
||||
// Callback to execute the batch update.
|
||||
class BatchUpdateStatementCallback implements StatementCallback<int[]>, SqlProvider {
|
||||
|
||||
@Nullable
|
||||
|
@ -1373,7 +1365,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!(param.isResultsParameter())) {
|
||||
if (!param.isResultsParameter()) {
|
||||
sqlColIndex++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue