I like Spring Data REST but I need to explore the possibility to use it without exposing directly our JPA Entities. Furthermore, our access layer is currently build using GenericDAO instead of repository (or Spring Data JPA).
So the idea is to build a custom spring data module that implementing the Repository interfaces allow me to benefit of all the other functionalities of Spring Data REST. The entities managed by our custom spring data module will be at the end DTOs of the original JPA entities.
I'm currently looking to spring-data-ldap as implementation to mimic as it looks as the most simple data module available but I'm facing with the following issue
we get an exception at the application startup saying
Parameter 0 of constructor in org.springframework.data.dspace.repository.support.DSpaceRepositoryFactoryBean required a bean of type 'java.lang.Class' that could not be found.
Action:
Consider defining a bean of type 'java.lang.Class' in your configuration.
DSpaceRepositoryFactoryBean is our implementation that just return a very simple DSpaceFactoryBean that always return a banal implementation of the CrudRepository (all methods return null)
#Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return SimpleDSpaceRepository.class;
}
have sense this approach? or will be better to give up with Spring Data REST and just use Spring MVC + HATEOS?
Related
I'm attempting to add Crate.IO capability to an existing Spring Data/Eclipselink/MySql web application. For this specific use case, we want to persist data to both MySql AND Crate (for evaluation purposes) in the most painless way possible. I'm using the Spring-Data-Crate project in order to be able to use Spring Data Repositories with Crate.
I've been able to setup a separate Crate specific entity manager with a filter to only utilize repos that implement CrateRepository. The problem I'm having is determining how to use the existing Spring Data/MySql entity classes with Crate. (or derive from them)
1) If I annotate an existing Spring Data #Entity class with the Spring-Data-Crate
#Table annotation, the mapping to the crate DB will fail because EclipseLink/JPA adds hidden persistence fields to entities objects that start with an underscore, which is apparently not allowed by the spring-data-crate adapter
2) I tried to use entity inheritance, with a base class that both the MySql and Crate entity can extend, with only the MySql entity having the spring data #Entity annotation. Unfortunately, this causes Spring Data to lose visibility of the base class fields unless the base class is annotated with #MappedSuperClass. But adding this annotation introduces the hidden "_"-prefixed persistence properties to the derived crate entity.
3) I could use separate entities entirely and have them implement a common interface, but I can't assign the interface as the type of the spring data crate repository.
... Not sure where to go from here
Spring Data Crate adapter project - https://github.com/KPTechnologyLab/spring-data-crate
Spring Data Crate Tutorial - https://crate.io/a/using-sprint-data-crate-with-your-java-rest-application/
i'm johannes from crate.
we didn't test the use of spring data crate in that manner so we can't state any information if this should or shouldn't work.
sorry, johannes
I am writing RESTful services using spring and hibernate. I read many resource in internet, but they did not clarify my doubts. Please explain me in details what are DAO, DTO and Service layers in spring framework? And why usage of these layers is required in spring to develop RESTfull API services.
First off, these concepts are Platform Agnostic and are not exclusive to Spring Framework or any other framework, for that matter.
Data Transfer Object
DTO is an object that carries data between processes. When you're working with a remote interface, each call it is expensive. As a result you need to reduce the number of calls. The solution is to create a Data Transfer Object that can hold all the data for the call. It needs to be serializable to go across the connection. Usually an assembler is used on the server side to transfer data between the DTO and any domain objects. It's often little
more than a bunch of fields and the getters and setters for them.
Data Access Object
A Data Access Object abstracts and encapsulates all access to
the data source. The DAO manages the connection with the data source to
obtain and store data.
The DAO implements the access mechanism required to work with the data source.
The data source could be a persistent store like an RDBMS, or a business service accessed via REST or SOAP.
The DAO abstracts the underlying data access implementation for the Service objects to
enable transparent access to the data source. The Service also delegates
data load and store operations to the DAO.
Service
Service objects are doing the work that the
application needs to do for the domain you're working with. It involves calculations based on inputs and
stored data, validation of any data that comes in from the presentation, and figuring out exactly what data
source logic to dispatch, depending on commands received from the presentation.
A Service Layer defines an application's boundary and its set of available operations from
the perspective of interfacing client layers. It encapsulates the application's business logic, controlling
transactions and coordinating responses in the implementation of its operations.
Recommended References
Martin Fowler has a great book on common Application Architecture Patterns named Patterns of Enterprise Application Architecture. There is also, Core J2EE Patterns that worth looking at.
DAO - Data Access Object:
An object that provides a common interface to perform all database operations like persistence mechanism.
public interface GenericDao<T> {
public T find(Class<T> entityClass, Object id);
public void save(T entity);
public T update(T entity);
public void delete(T entity);
public List<T> findAll(Class<T> entityClass);
}
See this example : Spring – DAO and Service layer
DTO - Data Transfer Object:
An object that carries data between processes in order to reduce the number of method calls means you combine more than one POJO entities in service layer.
For example a GET request /rest/customer/101/orders is to retrieve all the orders for customer id 101 along with customer details hence you need combine entity Customer and entity Orders with details.
Enterprise application is divided into tiers for easy maintenance and development. Tiers are dedicated to particular type of tasks like
presentation layer (UI)
Business layer
Data access layer (DAO, DTO)
Why this design:
Let's pick an example you have an application which reads data from db and performs some business logic on it then present it to user. Now if you want to change your DB let say earlier application was running on Oracle now you want to use mysql so if you don't develop it in tiers you will doing changes everywhere in application. But if you implement DAO in application then this can be done easily
DAO: Data Access Object is design pattern
just provide an interface for accessing data to service layer and provide different implementations for different data sources (Databases, File systems)
Example code:
public interface DaoService {
public boolean create(Object record);
public CustomerTemp findTmp(String id);
public Customer find(String id);
public List getAllTmp();
public List getAll();
public boolean update(Object record);
public boolean delete(Object record);
public User getUser(String email);
public boolean addUser(User user);
}
Service layer using Dao
#Service("checkerService")
public class CheckerServiceImpl implements CheckerService{
#Autowired
#Qualifier("customerService")
private DaoService daoService;
Now i can provide any implementation of DaoService interface.
Service and DTO are also used for separation of concerns.
DTO: The data object that we pass between different processes or within the same process. It can be a wrapper around the actual entity object. Using entity object as is for DTO is not safe and not recommended. Design of this object is based on various factors like simplicity of representation, security of exposing Ids, consumer requirement and so on.
In Spring, DTO can be formed with a simple model/pojo object.
DAO: The object responsible for CRUD operations.
In Spring, this can be an object that implements JPARepository interface, or any bean that connects with database and does a CRUD for us. Please remember your journey from JDBC to Hibernate to Spring data JPA. :)
Service: Core bean for business logic implementation. This object may has DAO object as its dependency. Core business logic for the particular use case will go here.
In Spring, Service object/bean can be created either by annotating the bean with #Service or #Component annotation or simply representing the object as a bean using java configuration. Make sure you inject all the required dependencies into the service bean for its heavy lifting job.
SERVICE LAYER:
It receives the request from controller layer and process the request to Persistence layer
#Controller:It is the annotation which initialize whole controller layer.
#Service:It is the annotation which initialize whole service layer.
#Repository: It is the annotation which initialize whole persistence layer.
DTO:
It is an Data Transfer object which used to pass the properties from service layer to persistence layer.
DAO:
It is an Data Access object. it is also known as persistence layer. In this DAO we receive property values from service layer in DTO object. Here we write an persistence logic to db.
In a Spring Data project if I am using multiple types of repositories i.e JPA repository and Mongo repository and if I am extending CrudRepository then how does Spring Data know which store to choose for that repository? It can use JPA or Mongo. Is it based on the annotation #Document or #Entity added on every persisting entity?
The decision which store a proxy created for a Spring Data repository interface is only made due to your configuration setup. Assume you have the following config:
#Configuration
#EnableJpaRepositories("com.acme.foo")
#EnableMongoRepositories("com.acme.foo")
class Config { }
This is going to blow up at some point as the interfaces in package com.acme.foo are both detected by the MongoDB and JPA infrastructure. To resolve this, both the JavaConfig and XML support allows you to define include and exclude filters so that you can either use naming conventions, additional annotations or the like:
#Configuration
#EnableJpaRepositories(basePackages = "com.acme.foo",
includeFilters = #Filter(JpaRepo.class))
#EnableMongoRepositories(base Packages = "com.acme.foo",
includeFilters = #Filter(MongoRepo.class))
class Config { }
In this case, the two annotations #JpaRepo and #MongoRepo (to be created by you) would be used to selectively trigger the detection by annotating the relevant repository interfaces with them.
A real auto-detection is sort of impossible as it's hard to tell which store you're targeting solely from the repository interface declaration and at the point in time when the bean definitions are created we don't even know about any further infrastructure (an EntityManager or the like) yet.
I'm trying to handle the Spring DAO Exceptions (http://docs.spring.io/spring/docs/4.0.3.RELEASE/spring-framework-reference/htmlsingle/#dao-exceptions) in the service layer of my application, just to discover that the exceptions in the spring-data-commons module don't extend org.springframework.dao.DataAccessException.DataAccessException.
Example: PropertyReferenceException.
As far as I can tell, all exceptions in this module, and maybe in the other sub-modules of Spring Data projects should extend DataAccessException.
Is there anything obvious that I'm not seeing here?
There is no need for Spring Data to use Spring Core's DataAccessException hierarchy as one may use the PersistenceExceptionTranslator. The latter translates thrown exceptions of e.g. Spring Data Repositories to a DataAccessException subtype.
PersistenceExceptionTranslator kicks in automatically when marking your repository with the "#Repository" annotation. The service (using the annotated repository) may catch the DataAccessException, if needed.
Found an article in springsource which describes how to manipulate the schema name at runtime.
http://forum.springsource.org/showthread.php?18715-changing-hibernate-schemas-at-runtime
We're using pure jpa however where were using a LocalContainerEntityManagerFactory and don't have access to Session or Conofiguration instances.
Can anyone provide insight on how to access the metadata at runtime (via the entitymanager) to allow modifying the schema?
Thanks
Changing meta-data at runtime is JPA provider specific. JPA allows you to pass a Map of provider specific properties when creating an EntityManagerFactory or EntityManager. JPA also allows you to unwrap() an EntityManager to a provider specific implementation.
If you are using EclipseLink you can set the schema using the setTableQualifier() API on the Session's login.
You can't using standard JPA (which is your requirement going by your question); it doesn't allow you to dynamically define metadata, only view (a limited amount of) specified metadata via its metamodel API. You'd have to delve into implementation specifics to get further, but then your portability goes down the toilet at that point, which isn't a good thing.
JDO, on the other hand, does allow you to dynamically define metadata (and hence schema) using standardised APIs.