From 4bb2e7a5bd7c7e65a98c4681a8be71e44d115f34 Mon Sep 17 00:00:00 2001 From: Mark Pollack Date: Fri, 8 Apr 2011 17:50:38 -0400 Subject: [PATCH] javadoc/doc changes. --- .../document/mongodb/index/CompoundIndex.java | 1 + .../mongodb/index/GeoSpatialIndexed.java | 2 +- .../data/document/mongodb/index/Indexed.java | 1 + .../data/document/mongodb/mapping/DBRef.java | 1 + .../document/mongodb/mapping/Document.java | 1 + .../data/document/mongodb/PersonExample.java | 3 +- .../data/document/mongodb/mapping/Person.java | 9 +- src/docbkx/reference/cross-store.xml | 14 +- src/docbkx/reference/mapping.xml | 231 ++++++++++--- src/docbkx/reference/mongodb.xml | 322 ++++++++++++++---- 10 files changed, 465 insertions(+), 120 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/CompoundIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/CompoundIndex.java index de5b01061..5d1651d76 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/CompoundIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/CompoundIndex.java @@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** + * Mark a class to use compound indexes. * @author Jon Brisbin */ @Target({ElementType.TYPE}) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java index ca24dbd8d..fdb067f2d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/GeoSpatialIndexed.java @@ -22,7 +22,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Mark a class property to be indexed using MongoDB's geospatial indexing feature. + * Mark a field to be indexed using MongoDB's geospatial indexing feature. * * @author Jon Brisbin */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/Indexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/Indexed.java index ec1f19411..51790a5d7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/Indexed.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/index/Indexed.java @@ -22,6 +22,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** + * Mark a field to be indexed using MongoDB's indexing feature. * @author Jon Brisbin */ @Target(ElementType.FIELD) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/DBRef.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/DBRef.java index 81cbe03a8..1bb9ae07d 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/DBRef.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/DBRef.java @@ -24,6 +24,7 @@ import java.lang.annotation.Target; import org.springframework.data.annotation.Reference; /** + * An annotation that indicates the annotated field is to be stored using a com.mongodb.DBRef * @author Jon Brisbin */ @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/Document.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/Document.java index f46a54687..e0a3d32e3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/Document.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/Document.java @@ -24,6 +24,7 @@ import java.lang.annotation.Target; import org.springframework.data.annotation.Persistent; /** + * Identifies a domain object to be persisted to MongoDB. * @author Jon Brisbin */ @Persistent diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java index ba238f456..ddbd2974b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java @@ -59,11 +59,12 @@ public class PersonExample { // mongoOps.updateFirst(new Query(where("firstName").is("Sven")), update("age", 24)); - mongoOps.updateFirst(query(where("firstName").is("Sven")), update("age", 24)); + p = mongoOps.findOne(query(whereId().is(p.getId())), PersonWithIdPropertyOfTypeString.class); log.debug("Updated: " + p); + //mongoOps.remove( query(whereId().is(p.getId())), p.getClass()); mongoOps.remove(p); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/Person.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/Person.java index 1a506ef57..fdb0dcd7f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/Person.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/Person.java @@ -48,6 +48,11 @@ public class Person { private List accounts; private T address; + + public Person(Integer ssn) { + this.ssn = ssn; + } + @PersistenceConstructor public Person(Integer ssn, String firstName, String lastName, Integer age, T address) { this.ssn = ssn; @@ -61,10 +66,6 @@ public class Person { return id; } - public void setId(String id) { - this.id = id; - } - public Integer getSsn() { return ssn; } diff --git a/src/docbkx/reference/cross-store.xml b/src/docbkx/reference/cross-store.xml index 25f4edf8e..a200a28c2 100644 --- a/src/docbkx/reference/cross-store.xml +++ b/src/docbkx/reference/cross-store.xml @@ -122,7 +122,7 @@ - Finally, you need to configure your project to use MomgoDB and also + Finally, you need to configure your project to use MongoDB and also configure the aspects that are used. The following XML snippet should be added to your application context: @@ -187,13 +187,13 @@ only cover the additional steps needed to persist part of your Entity in your Mongo database. First you need to identify the field you want persited. It should be a domain class and follow the general rules for the - Mongo mapping support covered in previous chapters. The filed you want + Mongo mapping support covered in previous chapters. The field you want persisted in MongoDB should be annotated using the - @RelatedDocument annotation. Well, that is really - all you need to do. The cross-store aspects take care of the rest. This - includes marking the field with @Transient so it won't be persisted using - JPA, keeping track of any changes made to the field value and writing them - to the database on succesfull transaction completion, loading teh document + @RelatedDocument annotation. That is really all you + need to do!. The cross-store aspects take care of the rest. This includes + marking the field with @Transient so it won't be persisted using JPA, + keeping track of any changes made to the field value and writing them to + the database on succesfull transaction completion, loading the document from MongoDB the first time the value is used in your application. Here is an example of a simple Entity that has a field annotated with @RelatedEntity. diff --git a/src/docbkx/reference/mapping.xml b/src/docbkx/reference/mapping.xml index b1c5c7bdc..9264fb41a 100644 --- a/src/docbkx/reference/mapping.xml +++ b/src/docbkx/reference/mapping.xml @@ -17,8 +17,54 @@
MongoDB Mapping Configuration + You can configure the MongoMappingConverter as well as Mongo and + MongoTemplate eithe using Java or XML based metadata. + + Here is an example using Spring's Java based configuration + + + @Configuration class to configure MongoDB mapping support + + +@Configuration +public class GeoSpatialAppConfig extends AbstractMongoConfiguration { + + @Bean + public Mongo mongo() throws Exception { + return new Mongo("localhost"); + } + + @Bean + public MongoTemplate mongoTemplate() throws Exception { + return new MongoTemplate(mongo(), "geospatial", "newyork", mappingMongoConverter()); + } + + // specify which package to scan for @Document objects. + public String getMappingBasePackage() { + return "org.springframework.data.document.mongodb"; + } + + // optional + @Bean + public LoggingEventListener<MongoMappingEvent> mappingEventsListener() { + return new LoggingEventListener<MongoMappingEvent>(); + } + + +} + + + AbstractMongoConfiguration requires you to + implement methods that define a Mongo as well as a + MongoTemplate object to the container. + AbstractMongoConfiguration also has a method you + can override named 'getMappingBasePackage' which + tells the configuration where to scan for classes annotated with the + @org.springframework.data.document.mongodb.mapping.Document + annotation. + Spring's Mongo namespace enables you to easily enable mapping - functionality + functionality in XML XML schema to configure MongoDB mapping support @@ -102,6 +148,141 @@ public class Person { document, making searches faster. +
+ Mapping annotation overview + + The MappingMongoConverter relies on metadata to drive the mapping + of objects to documents. An overview of the annotations is provided + below + + + + @Id - applied at the field level to mark + the field used for identiy purpose. + + + + @Document - applied at the class level to + indicate this class is a candidate for mapping to the database. You + can specify the name of the collection where the database will be + stored. + + + + @DBRef - applied at the field to indicate + it is to be stored using a com.mongodb.DBRef. + + + + @Indexed - applied at the field level to + describe how to index the field. + + + + @CompoundIndex - applied at the type level + to declare Compound Indexes + + + + @GeoSpatialIndexed - applied at the field + level to describe how to geoindex the field. + + + + @Transient - by default all private fields + are mapped to the document, this annotation excludes the field where + it is applied from being stored in the database + + + + @PersistenceConstructor - marks a given + constructor - even a package protected one - to use when + instantiating the object from the database. Constructor arguments + are mapped by name to the key values in the retrieved + DBObject. + + + + @Value - this annotation is part of the + Spring Framework . Within the mapping framework it can be applied to + constructor arguments. This lets you use a Spring Expression + Language statement to transform a key's value retrieved in the + database before it is used to construct a domain object. + + + + The mapping metadata infrastructure is defined in a seperate + spring-data-commons project that is technology agnostic. Specific + subclasses are using in the Mongo support to support annotation based + metadata. Other strategies are also possible to put in place if there is + demand. + + Here is an example of a more complex mapping. + + @Document +@CompoundIndexes({ + @CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}") +}) +public class Person<T extends Address> { + + @Id + private String id; + @Indexed(unique = true) + private Integer ssn; + private String firstName; + @Indexed + private String lastName; + private Integer age; + @Transient + private Integer accountTotal; + @DBRef + private List<Account> accounts; + private T address; + + + public Person(Integer ssn) { + this.ssn = ssn; + } + + @PersistenceConstructor + public Person(Integer ssn, String firstName, String lastName, Integer age, T address) { + this.ssn = ssn; + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + this.address = address; + } + + public String getId() { + return id; + } + + // no setter for Id. (getter is only exposed for some unit testing) + + public Integer getSsn() { + return ssn; + } + + +// other getters/setters ommitted + +} + + +
+ +
+ Id fields + + The @Id annotation is applied to fields. MongoDB lets you store + any type as the _id field in the database, including long and string. It + is of course common to use ObjectId for this purpose. If the value on + the @Id field is not null, it is stored into the database as-is. If it + is null, then the converter will assume you want to store an ObjectId in + the database. For this to work the field type should be either ObjectId, + String, or BigInteger. +
+
Compound Indexes @@ -184,50 +365,12 @@ public class Person {
- Handling Mapping Framework Events + Mapping Framework Events - Built into the MongoDB mapping framework are several - org.springframework.context.ApplicationEvent - events that your application can respond to by registering special beans - in the ApplicationContext. - - To intercept an object before it goes through the conversion - process (which turns your domain object into a - com.mongodb.DBObject), you'd register a subclass - of - org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener - that overrides the onBeforeConvert method. When the event - is dispatched, your listener will be called and passed the domain object - before it goes into the converter. - - - -public class BeforeConvertListener<BeforeConvertEvent, Person> extends AbstractMappingEventListener { - @Override - public void onBeforeConvert(Person p) { - ... does some auditing manipulation, set timestamps, whatever ... - } -} - - - - To intercept an object before it goes into the database, you'd - register a subclass of - org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener - that overrides the onBeforeSave method. When the event is - dispatched, your listener will be called and passed the domain object - and the converted com.mongodb.DBObject. - - - -public class BeforeSaveListener<BeforeSaveEvent, Person> extends AbstractMappingEventListener { - @Override - public void onBeforeSave(Person p, DBObject dbo) { - ... change values, delete them, whatever ... - } -} - - + Events are fired throughout the lifecycle of the mapping process. + This is described in the Lifecycle Events + section. Simply declaring these beans in your Spring ApplicationContext will cause them to be invoked whenever the event is dispatched. diff --git a/src/docbkx/reference/mongodb.xml b/src/docbkx/reference/mongodb.xml index ed7b70550..db787d377 100644 --- a/src/docbkx/reference/mongodb.xml +++ b/src/docbkx/reference/mongodb.xml @@ -84,7 +84,98 @@ Spring MongoDB support requires MongoDB 1.4 or higher and Java SE 5 or higher. The latest production release (1.8.x as of this writing) is - recommended. + recommended. An easy way to bootstrap setting up a working environment is + to create a Spring based project in STS. + + To create a Spring project in STS go to File -> New -> Spring + Template Project -> Simple Spring Utility Project --> press Yes when + prompted. Then enter a project and a package name such as + org.spring.mongodb.example. + + Then add the following to pom.xml dependencies section. + + <dependency> + <groupId>org.springframework.data</groupId> + <artifactId>spring-data-mongodb</artifactId> + <version>1.0.0.BUILD-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + The cglib dependency is there as we will use Spring's Java + configuration style. Also change the version of Spring in the pom.xml to + be + + <spring.framework.version>3.0.5.RELEASE</spring.framework.version> + + Next, in the org.spring.mongodb package in the sr/ctest/java + directory create a class as shown below. + + package org.spring.mongodb; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.document.mongodb.MongoTemplate; +import org.springframework.data.document.mongodb.config.AbstractMongoConfiguration; + +import com.mongodb.Mongo; + +@Configuration +public class MongoConfig extends AbstractMongoConfiguration { + + @Override + public Mongo mongo() throws Exception { + return new Mongo("localhost"); + } + + @Override + public MongoTemplate mongoTemplate() throws Exception { + return new MongoTemplate(mongo() , "database", "mongoexample"); + } + +} + + Then create a simple Person class to persist + + package org.spring.mongodb; + +public class Person { + + private String id; + + private String name; + + public Person(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + "]"; + } + +} + + And a main application to run + +
@@ -419,6 +510,16 @@ public class AppConfig {
+ +
+ Configuring the MongoConverter + + The SimpleMongoConverter is used by default but if you want to use + the more feature rich MappingMongoConverter there are a few steps. + Please refer to the mapping section for more + information. +
@@ -426,7 +527,7 @@ public class AppConfig { MongoTemplate provides a simple way for you to save, update, and delete your domain objects and map those objects to documents stored in - MongoDB. + MongoDB. Given a simple class such as Person @@ -490,7 +591,7 @@ Number of people = : 0 There was implicit conversion using SimpleMongoConverter between a String and ObjectId as stored in the database and recognizing a convention - of the property "Id" name. + of the property "Id" name. This example is meant to show the use of save, update and remove @@ -521,7 +622,7 @@ Number of people = : 0 argument only the object to save. In this case the default collection assigned to the template will be used unless the converter overrides this default through the use of more specific mapping metadata. You may - also call the save operation with a specific collection name. + also call the save operation with a specific collection name. When inserting or saving, if the Id property is not set, the assumption is that its value will be autogenerated by the database. As @@ -549,8 +650,7 @@ import static org.springframework.data.document.mongodb.query.Criteria.query; - The four save operations available to you are listed below. - + The four save operations available to you are listed below. @@ -580,7 +680,7 @@ import static org.springframework.data.document.mongodb.query.Criteria.query; - A similar set of insert operations is listed below + A similar set of insert operations is listed below @@ -810,7 +910,7 @@ import static org.springframework.data.document.mongodb.query.Update Methods for removing documents You can use several overloaded methods to remove an object from - the database. + the database. @@ -863,15 +963,11 @@ import static org.springframework.data.document.mongodb.query.Update API style so that you can easily chain together multiple method criteria and queries while having easy to understand code. Static imports in Java are used to help remove the need to see the 'new' keyword for creating - Query and Criteria instances so as to improve readability. + Query and Criteria instances so as to improve readability. GeoSpatial queries are also supported and are described more in the section GeoSpatial Queries. - - - GeoSpatial Queries -
Querying documents in a collection @@ -886,12 +982,11 @@ import static org.springframework.data.document.mongodb.query.Update Querying for documents using the MongoTemplate import static org.springframework.data.document.mongodb.query.Criteria.where; +import static org.springframework.data.document.mongodb.query.Query.query; - ... + ... - List<Person> result = mongoTemplate.find( - new Query(where("age").lt(50).and("accounts.balance").gt(1000.00d)), - Person.class); + List<Person> result = mongoTemplate.find(query(where("age").lt(50).and("accounts.balance").gt(1000.00d)),Person.class); @@ -903,7 +998,8 @@ import static org.springframework.data.document.mongodb.query.Update Criteria object. We recommend using a static import for org.springframework.data.document.mongodb.query.Criteria.where - to make the query more readable. + and Query.query to make the query more + readable. This query should return a list of Person objects that meet the specified criteria. The Criteria class has the following methods that @@ -1011,15 +1107,56 @@ import static org.springframework.data.document.mongodb.query.Update key to the current Criteria and retuns the newly created one - -
- The Query class has some additional methods - used to provide options for the query. + There are also methods on the Criteria class for geospatial + queries. Here is al isting but look at the section on GeoSpatial Queries to see them in + action. + + + + Criteria withinCenter + (Circle circle)Creates a geospatial + criterion using $within $center operators + + + + Criteria withinCenterSphere (Circle circle) + Creates a geospatial criterion using $within + $center operators. This is only available for Mongo 1.7 + and higher. + + + + Criteria withinBox + (Box box)Creates a geospatial + criterion using a $within $box operation + + + + + Criteria near + (Point point)Creates a geospatial + criterion using a $near operation + + + + Criteria nearSphere + (Point point) Creates a geospatial + criterion using $nearSphere$center operations. + This is only available for Mongo 1.7 and higher. + + + + The Query class has some additional + methods used to provide options for the query. + +
Methods for the Query class @@ -1226,7 +1363,7 @@ import static org.springframework.data.document.mongodb.query.Update are available on the Criteria class. There are also a few shape classes, Box, Circle, and Point that are - used in conjunction with geospatial related Criteria methods. + used in conjunction with geospatial related Criteria methods. To understand how to perform GeoSpatial queries we will use the following Venue class taken from the integration tests.which relies on @@ -1308,9 +1445,8 @@ List<Venue> venues = template.find(new Query(Criteria.where("location").ne
Index and Collection managment - index - - collection + MongoTemplate provides a few methods for managing indexes and + collections.
Methods for creating an Index @@ -1342,7 +1478,13 @@ List<Venue> venues = template.find(new Query(Criteria.where("location").ne - + You can create both standard indexes and geospatial indexes using + the classes IndexDefinition and + GeoSpatialIndex respectfully. For example, given + the Venue class defined in a previous section, you would declare a + geospatial query as shown below + + mongoTemplate.ensureIndex(new GeospatialIndex("location"));
@@ -1426,7 +1568,10 @@ List<Venue> venues = template.find(new Query(Criteria.where("location").ne
Executing Commands - exec plain old JS. + You can also get at the Mongo driver's collection.command( ) method + using the executeCommand methods on MongoTemplate. These will also perform + exception translation into Spring's Data Access Exception + hierarchy.
Methods for executing commands @@ -1444,50 +1589,101 @@ List<Venue> venues = template.find(new Query(Criteria.where("location").ne jsonCommand) Execute the a MongoDB command expressed as a JSON string. - - - <T> T execute - (CollectionCallback<T> action) - Executes the given CollectionCallback on the default - collection. - - - - <T> T execute - (String collectionName, - CollectionCallback<T> action) Executes the given - CollectionCallback on the collection of the given name.update - using the $addToSet update modifier - - - - <T> T execute - (DbCallback<T> action) - Executes a DbCallback translating any exceptions as - necessary. - - - - <T> T executeInSession - (DbCallback<T> action) Executes the - given DbCallback within the same connection to the database so as - to ensure consistency in a write heavy environment where you may - read the data that you wrote. -
-
+
Lifecycle Events - The lifecycle events are.... + Built into the MongoDB mapping framework are several + org.springframework.context.ApplicationEvent events + that your application can respond to by registering special beans in the + ApplicationContext. By being based off Spring's + ApplicationContext event infastructure this enables other products, such + as Spring Integration, to easily receive these events as they are a well + known eventing mechanism in Spring based applications. + + To intercept an object before it goes through the conversion process + (which turns your domain object into a + com.mongodb.DBObject), you'd register a subclass of + org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener + that overrides the onBeforeConvert method. When the event is + dispatched, your listener will be called and passed the domain object + before it goes into the converter. + + + +public class BeforeConvertListener<BeforeConvertEvent, Person> extends AbstractMappingEventListener { + @Override + public void onBeforeConvert(Person p) { + ... does some auditing manipulation, set timestamps, whatever ... + } +} + + + + To intercept an object before it goes into the database, you'd + register a subclass of + org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener + that overrides the onBeforeSave method. When the event is + dispatched, your listener will be called and passed the domain object and + the converted com.mongodb.DBObject. + + + +public class BeforeSaveListener<BeforeSaveEvent, Person> extends AbstractMappingEventListener { + @Override + public void onBeforeSave(Person p, DBObject dbo) { + ... change values, delete them, whatever ... + } +} + + + + Simply declaring these beans in your Spring ApplicationContext will + cause them to be invoked whenever the event is dispatched. + + The list of callback methods that are present in + AbstractMappingEventListener are + + + + onBeforeConvert - called in + MongoTemplate insert, insertList and save operations before the object + is converted to a DBObject using a MongoConveter. + + + + onBeforeSave - called in MongoTemplate + insert, insertList and save operations before + inserting/saving the DBObject in the database. + + + + onAfterSave - called in MongoTemplate + insert, insertList and save operations after + inserting/saving the DBObject in the database. + + + + onAfterLoad - called in MongoTempnlate + find, findAndRemove, findOne and getCollection methods after the + DBObject is retrieved from the database. + + + + onAfterConvert - called in + MongoTempnlate find, findAndRemove, findOne and getCollection methods + after the DBObject retrieved from the database was converted to a + POJO. + +
-
+
Exception Translation The Spring framework provides exception translation for a wide @@ -1508,7 +1704,7 @@ List<Venue> venues = template.find(new Query(Criteria.where("location").ne sure that you will be able to catch all database related exception within a single try-catch block. Note, that not all exceptions thrown by the MongoDB driver inherit from the MongoException class. The inner exception - and message are preserved so no information is lost. + and message are preserved so no information is lost. Some of the mappings performed by the MongoExceptionTranslator are: com.mongodb.Network to DataAccessResourceFailureException and