DAO and dependency injection, advice? - java

This is the first time im using the DAO pattern. From what I've read so far, implementing this pattern will help me seperate my calling code (controller) from any persistence implementation - exactly what I want; that is, I don't want to be restrcited to the use of any particular database or 3rd party libraries.
I'm creating some test code (in TDD fashion) using MongoDB and morphia (as an example), with morphia's provided BasicDAO class.
As far as I can tell, extending BasicDAO<T, V> requires a constructor that accepts Morphia and Mongo objects; these are very specific (3rd party) types that I don't really want floating around outside of the DAO class itself.
How can I have more of a pluggable architecture? By this I mean, what should I look into re being able to configure my application to use a specific DAO with specific configuration arguments, external to the actual source?

A "pluggable" DAO layer is usually/always based on an interface DAO. For example, lets consider a quite generic simple one:
public interface GenericDAO <T, K extends Serializable> {
List<T> getAll(Class<T> typeClass);
T findByKey(Class<T> typeClass, K id);
void update(T object);
void remove(T object);
void insert(T object);
}
(This is what you have in Morphia's generic DAO)
Then you can develop different several generic DAO implementations, where you can find different fields (reflected in constructor parameters, setters and getters, etc). Let's assume a JDBC-based one:
public class GenericDAOJDBCImpl<T, K extends Serializable> implements GenericDAO<T, K extends Serializable> {
private String db_url;
private Connection;
private PreparedStatement insert;
// etc.
}
Once the generic DAO is implemented (for a concrete datastore), getting a concrete DAO would be a no brainer:
public interface PersonDAO extends GenericDAO<Person, Long> {
}
and
public class PersonDAOJDBCImpl extends GenericDAOJDBCImpl<Person, Long> implements PersonDAO {
}
(BTW, what you have in Morphia's BasicDAO is an implementation of the generic DAO for MongoDB).
The second thing in the pluggable architecture is the selection of the concrete DAO implementation. I would advise you to read chapter 2 from Apress: Pro Spring 2.5 ("Putting Spring into "Hello World") to progressively learn about factories and dependency injection.

Spring does DI for you using configurations and it's widely used.

Hi i am not an expert in java. but trying to give a solution.
you can have a superclass where all the connection related stuff happens and any other base class where you can extend and use it.
Later any switch in your DB for specific 3rd party drivers you can rewrite the superclass.
Again I am no expert. Just trying around here to learn. :)

A couple standard DI frameworks are Spring and Guice. Both these frameworks facilitate TDD.

Related

Injecting one of data repositories in Service layer in Spring

In my web app I have two different data storages - db and file. In application.properties I can set which one I want to use. I use Spring Data JPA for accessing object from db, so my DataBaseRepository extends CrudRepository.
I want to inject one inteface of Repository in Service layer, and
implementation will depend on chosen profile(in application.properties).
Problem is that my FileRepository doesn't implement CrudRepository, so my repositories haven't common interface for injecting.
Approach 1:Suppose, that my FileRepository extends CrudRepository(and I mark FileRepository with #NoRepositoryBean)
Problem: my implementation of FileRepository must implement many methods, which I don't need(I don't know if it is normal approach and it is worked)
Approach2:don't use CrudRepository interface
Problem: writing many boilerplate code
So, please tell me about another approaches,if they exist in such situation, or say which one is better. Any help is appreciated.
You could create a CustomCrudRepository that extends CrudRepository and a BaseRepository.The BaseRepository interface contains every method that has to be supported by any implementation. Most likely copy the signature from CrudRepository. Than inject based on the BaseRepository.
Hard to explain so see the following example without generics. You can add them on your own.
public interface BaseRepo {
// common methods
long count();
...
}
#NoRepositoryBean
interface CustomCrudRepository extends CrudRepository, BaseRepo {
}
interface EntityRepository extends CustomCrudRepository {
}
class FileRepository implements BaseRepo {
#Override
public long count() {
return 0;
}
}
#Service
class SomeService {
#Autowired
private BaseRepo repo;
}

Spring + Mongo + Generics + Flexibility

The following code doesn't work (of course), because the marked line does not compile:
MyClass {
//singleton stuff
private static MyClass instance;
private MyClass () {}
public static MyClass getInstance() {
if(instance==null) {
instance = new MyClass ();
}
return instance;
}
// method creating problems
public NonGenericSuperClassOfGenericClass create(Class<?>... classes) {
if(someCondition)
return new GenericClass<classes[0],classes[1]>; // DOES NOT COMPILE
else
return new OtherGenericClass<classes[0]>;
}
}
Therefore, I actually don't know whether "create" will return
GenericClass<classes[0],classes[1]>
or
OtherGenericClass<classes[0]>
which have different numbers of parameters.
This happens because I'm using Spring and I plan to use MongoDB, but in the future I may need to switch to something different (e.g. Hibernate).
The class GenericClass is something like:
GenericClass<PersistetType1, Long>
or
GenericClass<PersistentType2, Long>
where PersistentType1/2 are classes that I need to finally store in the DB, while, GenericClass is a sort of Proxy to access Mongo APIs. In fact, it looks like:
public MongoTemplate getTemplate();
public void save(T toInsert);
public List<T> select(Query selectionQuery);
public T selectById(ID id);
public WriteResult update(Query selectionQuery, Update updatedAttributes);
public void delete(T toRemove);
public void delete(Query selectionQuery);
Now, what?
From Controllers (or Entity, if you are picky) I need to instantiate the repository and invoke any methods. This causes the Controllers to be coupled with MongoDB, i.e. they explicitly have to instantiate such GenericClass, which is actually called MongoRepository and is strictly dependent on Mongo (in fact it is a generic with exactly two "degrees of freedom").
So, I decided to create MyClass, that is a further proxy that isolates Controllers. In this way, Controller can get the single instance of MyClass and let it create a new instance of the appropriate repository. In particular, when "somecondition" is true, it means that we want to use MongoRepository (when it is false, maybe, a need to instantiate a Hibernate proxy, i.e. HibernateRepository). However, MongoRepository is generic, therefore it requires some form of instantiation, that I hoped to pass as a parameter.
Unfortunately, generics are resolved at compile time, thus they don't work for me, I guess.
How can I fix that?
In order to decouple the underlying persistence store from your application logic I would use the DAO approach.
Define the interface of your DAO with the required methods e.g. save, update etc. And then provide an implementation for each persistence provider you might need e.g.UserAccess might be the interface which you could implement as HibernateUserAccess and MongoUserAccess. In each implementation you inject the appropriate Template e.g. Mongo or Hibernate and use that to complete the persistence operation.
The issue you might have is that your load operation would return an instance of User, this would need to vary across persistence providers i.e. JPA annotations would be different to the Spring Data annotations needed for MongoDB (leaky abstraction).
I would probably solve that by creating a User interface to represent the result of the persistence operation and having an implementation for each persistence provider. Either that or return a common model which you build from the results of a JPA or Mongo load.

Java Interface Inheritance and Extending

Imagine you are working on a mature product and a new search feature is requested that is required for 50% of your product. Now assuming you have an established interface inheritance relationship with SomeDao that you don't want to break...
public interface MoneyDao
extends SomeDao<MoneyEntity>
{
//Operation common in much of the application
List<MoneyEntity> findByCriteria(MoneyCriteria criteria);
}
...is there a way to expose the method 'findByCriteria(..)' without repeating it in all the other places similar to MoneyDao where it's required in a cleaner way?
Bare in mind I want to avoid casting in to a new type where its used and modifying SomeDao if at all possible.
Regards,
James
Can you break the findByCriteria into its own interface and extend it in MoneyDao? Something like this:
public interface MoneyDao
extends SomeDao<MoneyEntity>, MoneyFinder
{
}
public interface MoneyFinder
{
//Operation common in much of the application
List<MoneyEntity> findByCriteria(MoneyCriteria criteria);
}
Now your class(es) implementing MoneyDao don't need to change, but you can pass around just the findByCriteria using MoneyFinder.
Its all depends on if you want a class that is searchable and is a Dao, in other words its if your Searchable class must also be a Dao. If its this case I would use a generic approach to make your Dao Searchable.
interface SearchableDao<Entity, Criteria> extends SomeDao<Entity>
{
List<Entity> findByCriteria(Criteria criteria);
}
Now your class can be a simple Dao or a SearchableDao. SearchableDao is also a simple Dao.
class MoneyDao implements SearchableDao<MoneyEntity, MoneyCriteria>
{
List<MoneyEntity> findByCriteria(MoneyCriteria criteria) {...}
}

Single DAO & generic CRUD methods (JPA/Hibernate + Spring)

Following my previous question, DAO and Service layers (JPA/Hibernate + Spring), I decided to use just a single DAO for my data layer (at least at the beginning) in an application using JPA/Hibernate, Spring and Wicket. The use of generic CRUD methods was proposed, but I'm not very sure how to implement this using JPA. Could you please give me an example or share a link regarding this?
Here is an example interface:
public interface GenericDao<T, PK extends Serializable> {
T create(T t);
T read(PK id);
T update(T t);
void delete(T t);
}
And an implementation:
public class GenericDaoJpaImpl<T, PK extends Serializable>
implements GenericDao<T, PK> {
protected Class<T> entityClass;
#PersistenceContext
protected EntityManager entityManager;
public GenericDaoJpaImpl() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass()
.getGenericSuperclass();
this.entityClass = (Class<T>) genericSuperclass
.getActualTypeArguments()[0];
}
#Override
public T create(T t) {
this.entityManager.persist(t);
return t;
}
#Override
public T read(PK id) {
return this.entityManager.find(entityClass, id);
}
#Override
public T update(T t) {
return this.entityManager.merge(t);
}
#Override
public void delete(T t) {
t = this.entityManager.merge(t);
this.entityManager.remove(t);
}
}
Based on the article Don't repeat the DAO we used this kind of technique for many years. We always struggled with problems with our patterns after we realized that we made a big mistake.
By using an ORM tool such as Hibernate or JPA you will not have to think DAO and Service layer separately. You can use EntityManager from your service classes as you know the lifecycle of transactions and the logic of your entity classes there.
Do you save any minute if you call myDao.saveEntity instead of simply entityManager.saveEntity? No. You will have an unnecessary dao class that does nothing else but will be a wrapper around EntityManager. Do not afraid to write selects in your service classes with the help of EntityManager (or session in hibernate).
One more note: You should define the borders of your service layer and do not let programmers to return or wait for Entity classes. The UI or WS layer programmers should not know at all about entity classes only about DTO-s. Entity objects have lifecycles that most of the programmers do not know about. You will have really serious issues if you store an entity object in a session data and try to update it back to the database seconds or hours later. Well you may would not do it but a programmer of the UI who knows the parameter types and return types of your service layer only would do to save some lines of code.
I was looking for this same thing. I found what appears to be exactly that- the Spring-Data JPA project provided by SpringSource. This is a code port from Hades and has now (Early 2011) been swallowed by Spring and better integrated.
It allows you to use a single dao (SimpleJpaRepository) with a static create, or extend the base JpaRepository class to create any object specific dao with ready made CRUD+ methods. Also allows grails like queries just by using params names as the name of the method- in the interface (no implementation required!) i.e. findByLastname(String lastName);
Looks very promising- being part of Spring projects will certainly ensure some future for it too.
I have begun implementing this in my upcoming project now.
if you are looking for a third party implementation , you can check
http://www.altuure.com/projects/yagdao/ . it is a nnotation based generic DAO framework which supports JPA and hibernate
You may also have a look at http://codeblock.engio.net/data-persistence-and-the-dao-pattern/
The related code can be found on github https://github.com/bennidi/daoism
It has integration with Spring and configuration examples for Hibernate and EclipseLink

Add Java Annotation to inherited field

I'm working on something that might benefit from a pattern like the following:
public abstract class SomeBuisnessThingy()
{
protected int someDatapoint;
}
public class ADatabaseThingy() extends SomeBusinessThingy()
{
#SomeJPAAnnotation
???? someDatapoint;
}
public class AWebServiceThingy() extends SomeBusinessThingy()
{
#SomeSOAPStuff
???? someDatapoint;
}
It smells more like an interface than an abstract class, but the same thing needs to be done. I have a DB implementation of that class and a WS implementation of that class.
Those representations are very similar, but may be different. For example the WS class may expose a field as a String so a 3rd party can easily do an integration, it can also be splot into its own package so we can hand a customer some lightweight WebService or POJO classes without all the baggage of the DB or a JPA framework coming with it. Perhaps it could be used to create the basic classes needed for something then switch between persistence frameworks that use different annotations.
Is it possible to ADD annotations to inherited fields?
No. If you need to annotate inherited members, you need to annotate the methods, not the fields.

Categories

Resources