Merge branch '6.0.x'
# Conflicts: # gradle.properties # spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java
This commit is contained in:
commit
064cd3b7af
|
@ -281,8 +281,8 @@ Spring Data JPA, make sure to set up deferred bootstrapping for its repositories
|
||||||
[[orm-jpa-dao]]
|
[[orm-jpa-dao]]
|
||||||
== Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager`
|
== Implementing DAOs Based on JPA: `EntityManagerFactory` and `EntityManager`
|
||||||
|
|
||||||
NOTE: Although `EntityManagerFactory` instances are thread-safe, `EntityManager` instances are
|
NOTE: Although `EntityManagerFactory` instances are thread-safe, `EntityManager` instances
|
||||||
not. The injected JPA `EntityManager` behaves like an `EntityManager` fetched from an
|
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
|
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
|
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.
|
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
|
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
|
using an injected `EntityManagerFactory` or `EntityManager`. Spring can understand the
|
||||||
`@PersistenceUnit` and `@PersistenceContext` annotations both at the field and the method level
|
`@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
|
if a `PersistenceAnnotationBeanPostProcessor` is enabled. The following example shows a plain
|
||||||
that uses the `@PersistenceUnit` annotation:
|
JPA DAO implementation that uses the `@PersistenceUnit` annotation:
|
||||||
|
|
||||||
[tabs]
|
[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 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
|
the factory. You can avoid this by requesting a transactional `EntityManager` (also called a
|
||||||
called a "`shared EntityManager`" because it is a shared, thread-safe proxy for the actual
|
"`shared EntityManager`" because it is a shared, thread-safe proxy for the actual transactional
|
||||||
transactional EntityManager) to be injected instead of the factory. The following example shows how to do so:
|
EntityManager) to be injected instead of the factory. The following example shows how to do so:
|
||||||
|
|
||||||
[tabs]
|
[tabs]
|
||||||
======
|
======
|
||||||
|
@ -430,19 +430,19 @@ The `@PersistenceContext` annotation has an optional attribute called `type`, wh
|
||||||
`EntityManager` proxy. The alternative, `PersistenceContextType.EXTENDED`, is a completely
|
`EntityManager` proxy. The alternative, `PersistenceContextType.EXTENDED`, is a completely
|
||||||
different affair. This results in a so-called extended `EntityManager`, which is not
|
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
|
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
|
Spring-managed singleton bean. Extended `EntityManager` instances are only supposed to be used#
|
||||||
stateful components that, for example, reside in a session, with the lifecycle of the
|
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
|
`EntityManager` not tied to a current transaction but rather being completely up to the
|
||||||
application.
|
application.
|
||||||
|
|
||||||
.Method- and field-level Injection
|
.Method- and field-level Injection
|
||||||
****
|
****
|
||||||
You can apply annotations that indicate dependency injections (such as `@PersistenceUnit` and
|
You can apply annotations that indicate dependency injections (such as `@PersistenceUnit` and
|
||||||
`@PersistenceContext`) on field or methods inside a class -- hence the
|
`@PersistenceContext`) on field or methods inside a class -- hence the expressions
|
||||||
expressions "`method-level injection`" and "`field-level injection`". Field-level
|
"`method-level injection`" and "`field-level injection`". Field-level annotations are
|
||||||
annotations are concise and easier to use while method-level annotations allow for further
|
concise and easier to use while method-level annotations allow for further processing of the
|
||||||
processing of the injected dependency. In both cases, the member visibility (public,
|
injected dependency. In both cases, the member visibility (public, protected, or private)
|
||||||
protected, or private) does not matter.
|
does not matter.
|
||||||
|
|
||||||
What about class-level annotations?
|
What about class-level annotations?
|
||||||
|
|
||||||
|
@ -451,9 +451,9 @@ injection.
|
||||||
****
|
****
|
||||||
|
|
||||||
The injected `EntityManager` is Spring-managed (aware of the ongoing transaction).
|
The injected `EntityManager` is Spring-managed (aware of the ongoing transaction).
|
||||||
Even though the new DAO implementation uses method-level
|
Even though the new DAO implementation uses method-level injection of an `EntityManager`
|
||||||
injection of an `EntityManager` instead of an `EntityManagerFactory`, no change is
|
instead of an `EntityManagerFactory`, no change is required in the bean definition
|
||||||
required in the application context XML, due to annotation usage.
|
due to annotation usage.
|
||||||
|
|
||||||
The main advantage of this DAO style is that it depends only on the Java Persistence API.
|
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,
|
No import of any Spring class is required. Moreover, as the JPA annotations are understood,
|
||||||
|
|
|
@ -660,7 +660,7 @@ class DefaultConversionServiceTests {
|
||||||
foo.add("2");
|
foo.add("2");
|
||||||
foo.add("3");
|
foo.add("3");
|
||||||
@SuppressWarnings("unchecked")
|
@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")));
|
new TypeDescriptor(getClass().getField("genericList")));
|
||||||
assertThat(bar).containsExactly(1, 2, 3);
|
assertThat(bar).containsExactly(1, 2, 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ class CollectionToCollectionConverterTests {
|
||||||
@Test
|
@Test
|
||||||
void listToCollectionNoCopyRequired() throws NoSuchFieldException {
|
void listToCollectionNoCopyRequired() throws NoSuchFieldException {
|
||||||
List<?> input = new ArrayList<>(Arrays.asList("foo", "bar"));
|
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);
|
new TypeDescriptor(getClass().getField("wildcardCollection")))).isSameAs(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ class CollectionToCollectionConverterTests {
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
list.add("A");
|
list.add("A");
|
||||||
list.add("C");
|
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 {
|
void wildcardMap() throws Exception {
|
||||||
Map<String, String> input = new LinkedHashMap<>();
|
Map<String, String> input = new LinkedHashMap<>();
|
||||||
input.put("key", "value");
|
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);
|
assertThat(converted).isEqualTo(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -417,9 +417,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||||
logger.debug("Executing SQL statement [" + sql + "]");
|
logger.debug("Executing SQL statement [" + sql + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Callback to execute the statement.
|
||||||
* Callback to execute the statement.
|
|
||||||
*/
|
|
||||||
class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
|
class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -445,9 +443,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||||
logger.debug("Executing SQL query [" + sql + "]");
|
logger.debug("Executing SQL query [" + sql + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Callback to execute the query.
|
||||||
* Callback to execute the query.
|
|
||||||
*/
|
|
||||||
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
|
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -542,9 +538,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||||
logger.debug("Executing SQL update [" + sql + "]");
|
logger.debug("Executing SQL update [" + sql + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Callback to execute the update statement.
|
||||||
* Callback to execute the update statement.
|
|
||||||
*/
|
|
||||||
class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
|
class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
|
||||||
@Override
|
@Override
|
||||||
public Integer doInStatement(Statement stmt) throws SQLException {
|
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");
|
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 {
|
class BatchUpdateStatementCallback implements StatementCallback<int[]>, SqlProvider {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -1373,7 +1365,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(param.isResultsParameter())) {
|
if (!param.isResultsParameter()) {
|
||||||
sqlColIndex++;
|
sqlColIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue