I am working with Spring Boot on a project. JdbcNamedTemplates are used in my DAOs to access data. I write queries in my daos and then Map some parameters at runtime to get correct data.
Now, I have to handle retrieving data from multiple identical tables depending on the request. Retrieval logic is the same except I need to use different table names. JdbcTemplate does not allow using table names as parameters. I do not want to use string formatting as I wish my queries to be final.
I could create abstract class with most of the functionality and the concrete classes that extend it to handle differences in table names (basicly, have method "getTableName()"). This works. However, it seems like I am creating a lot of classes and I would like to create less of them.
Are there better ways to do it?
I was thinking that using interfaces for specific tablenames would be nice, but I cant wrap my head around how that could work with Spring and Autowiring.
UPDATE:
Just giving a sample of what I would like to improve.
So far I have couple of abstract DAOs like this. They do the database talk.
public abstract class Dao1 {
private static final String PARAM = "p";
private final String QUERY1 = " SELECT * FROM " + getTableName() + " WHERE something";
//here we would also have autowired jdbcNamedTemplate and maybe some other stuff.
public getAll() {
//map parameters, do query return results
}
protected abstract String getTableName();
}
Next, I have couple of data access objects that implemenent abstract method getTableName(). So if the table was "Autumn", I woould have.
#Component
public class AutumnDao1 extends Dao1 {
#Override
protected String getTableName() {
return "AUTUMN";
}
}
So from example above you can see that for each abstract dao I would have to make couple of Concrete Daos (autumn, winter, spring, summer). This is acceptable for now, but at some point this might grow to quite sizeable collection of daos.
I would like to know if there is a way to avoid that by for instance creating just one class / interface for each "season" / name and somehow attatching it to Dao1, Dao2 etc, as needed. I only know which name is relevant when the user request arrive.
With #Qualifier("nameOfBean") you can inject the instance you are looking for.
If you have, for instance:
#Component
public class AutumnDao1 extends Dao1 {
#Override
protected String getTableName() {
return "AUTUMN";
}
}
#Component
public class SummerDao1 extends Dao1 {
#Override
protected String getTableName() {
return "SUMMER";
}
}
In this case you are creating two beans that can be injected in the parent class Dao1. To inject the right one you should do:
#Autowire
#Qualifier("autumnDao1")
private Dao1 autumnDao;
#Autowire
#Qualifier("summerDao1")
private Dao1 summerDao;
Try this!
Related
First, please let me introduce a minimal scene demo to explain the problem.
Let's say i have a strategy pattern interface.
public interface CollectAlgorithm<T> {
public List<T> collect();
}
And a implementation of this strategy, the ConcreteAlgorithm.
public class ConcreteAlgorithm implements CollectAlgorithm<Integer> {
#Resource
QueryService queryService;
#Override
public List<Integer> collect() {
// dummy ...
return Lists.newArrayList();
}
}
As you can see, the implementation depend on some query operation provided by a #Service component.
The ConcreteAlgorithm class will be created by new in some places, then the collect method will be called.
I've read some related link like Spring #Autowired on a class new instance, and know that the above code cannot work, since the instance created by new has a #Resource annotated member.
I'm new to Spring/Java, and i wonder if there are some ways, or different design, to make scene like above work.
I've thought about use factory method, but it seems that it will involve many unchecked type assignment since i provided a generic interface.
UPDATE
To make it more clear, i add some detail about the problem.
I provide a RPC service for some consumers, with an interface like:
public interface TemplateRecommendService {
List<Long> recommendTemplate(TemplateRecommendDTO recommendDTO);
}
#Service
public class TemplateRecommandServiceImpl implements TemplateRecommendService {
#Override
public List<Long> recommendTemplate(TemplateRecommendDTO recommendDTO) {
TemplateRecommendContext context = TemplateRecommendContextFactory.getContext(recommendDTO.getBizType());
return context.process(recommendDTO);
}
}
As you can see, i will create different context by a user pass field, which represent different recommendation strategy. All the context should return List<Long>, but the pipeline inside context is totally different with each other.
Generally there are three main stage of the context process pipeline. Each stage's logic might be complicated and varied. So there exists another layer of strategy pattern.
public abstract class TemplateRecommendContextImpl<CollectOut, PredictOut> implements TemplateRecommendContext {
private CollectAlgorithm<CollectOut> collectAlgorithm;
private PredictAlgorithm<CollectOut, PredictOut> predictAlgorithm;
private PostProcessRule<PredictOut> postProcessRule;
protected List<CollectOut> collect(TemplateRecommendDTO recommendDTO){
return collectAlgorithm.collect(recommendDTO);
}
protected List<PredictOut> predict(TemplateRecommendDTO recommendDTO, List<CollectOut> predictIn){
return predictAlgorithm.predict(recommendDTO, predictIn);
}
protected List<Long> postProcess(TemplateRecommendDTO recommendDTO, List<PredictOut> postProcessIn){
return postProcessRule.postProcess(recommendDTO, postProcessIn);
}
public /*final*/ List<Long> process(TemplateRecommendDTO recommendDTO){
// pipeline:
// dataCollect -> CollectOut -> predict -> Precision -> postProcess -> Final
List<CollectOut> collectOuts = collect(recommendDTO);
List<PredictOut> predictOuts = predict(recommendDTO, collectOuts);
return postProcess(recommendDTO, predictOuts);
}
}
As for one specific RecommendContext, its creation likes below:
public class ConcreteContextImpl extends TemplateRecommendContextImpl<GenericTempDO, Long> {
// collectOut, predictOut
ConcreteContextImpl(){
super();
setCollectAlgorithm(new ShopDecorateCrowdCollect());
setPredictAlgorithm(new ShopDecorateCrowdPredict());
setPostProcessRule(new ShopDecorateCrowdPostProcess());
}
}
Instead od using field oriented autowiring use constructor oriented one - that will force the user, creating the implementation instance, to provide proper dependency during creation with new
#Service
public class ConcreteAlgorithm implements CollectAlgorithm<Integer> {
private QueryService queryService;
#Autowired // or #Inject, you cannot use #Resource on constructor
public ConcreteAlgorithm(QueryService queryService) {
this.queryService = queryService;
}
#Override
public List<Integer> collect() {
// dummy ...
return Lists.newArrayList();
}
}
There are 4 (+1 Bonus) possible approaches I can think of, depending on your "taste" and on your requirements.
1. Pass the service in the constructor.
When you create instances of your ConcreteAlgorithm class you provide the instance of the QueryService. Your ConcreteAlgorithm may need to extend a base class.
CollectAlgorithm<Integer> myalg = new ConcreteAlgorithm(queryService);
...
This works when the algorithm is a stateful object that needs to be created every time or, with some variations, when you actually don't know the algorithm at all as it comes from another library (in which case you might have a factory or, in rare cases which most likely don't fit your scenario, create the object through reflection).
2. Turn your algorithm into a #Component
Annotate your ConcreteAlgorithm with the #Component annotation and then reference it wherever you want. Spring will take care of injecting the service dependency when the bean is created.
#Component
public class ConcreteAlgorithm implements CollectAlgorithm<Integer> {
#Resource
QueryService queryService;
....
}
This is the standard and usually preferred way in Spring. It works when you know ahead of time what all the possible algorithms are and such algorithms are stateless.
This is the typical scenario. I don't know if it fits your needs but I would expect most people to be looking for this particular option.
Note that in the above scenario the recommendation is to use constructor-based injection. In other words, I would modify your implementation as follows:
#Component
public class ConcreteAlgorithm implements CollectAlgorithm<Integer> {
final QueryService queryService;
#Autowired
public ConcreteAlgorithm(QueryService queryService) {
this.queryService = queryService;
}
#Override
public List<Integer> collect() {
// dummy ...
return Lists.newArrayList();
}
}
On the most recent versions of Spring you can even omit the #Autowired annotation.
3. Implement and call a setter
Add a setter for the QueryService and call it as needed.
CollectAlgorithm<Integer> myalg = new ConcreteAlgorithm();
myalg.setQueryService(queryService);
...
This works in scenarios like those of (1), but lifts you from the need of passing parameters to the constructor, which "may" help getting rid of reflection in some cases.
I don't endorse this particular solution however as it forces to know that you have to call the setQueryService method prior to invoking other methods. Quite error-prone.
4. Pass the QueryService directly to your collect method.
Possibly the easiest solution.
public interface CollectAlgorithm<T> {
public List<T> collect(QueryService queryService);
}
public class ConcreteAlgorithm implements CollectAlgorithm<Integer> {
#Override
public List<Integer> collect(QueryService queryService) {
// dummy ...
return Lists.newArrayList();
}
}
This works well if you want your interface to be a functional one, to be used in collections.
Bonus: Spring's SCOPE_PROTOTYPE
Spring doesn't only allow to instantiate singleton beans but also prototype beans. This effectively means it will act as a factory for you.
I will leave this to an external example, at the following URL:
https://www.boraji.com/spring-prototype-scope-example-using-scope-annotation
This "can" be useful in specific scenarios but I don't feel comfortable recommending it straight away as it's significantly more cumbersome.
I am going to implement Data Mapper pattern to store data in different storages/databases.
What is the best OOP pattern to implement this concept?
For example, I have User model class
public class User
{
private int id;
private String name;
private String surname;
/* getters, setters and model-level business logic */
}
and appropriate Data Mapper class
public class UserMapper
{
public User findById(int id)
{
// perform query to MySQL, Redis or another DB
}
/* other methods */
}
Is it a good idea to use Strategy pattern by creating multiple storage strategy classes and then inject them into DataMapper class?
public class UserMySQLStorageStrategy extends UserStorageStrategy
{
public User findById(int id)
{
// perform query to MySQL
}
}
public class UserRedisStorageStrategy extends UserStorageStrategy
{
public User findById(int id)
{
// perform query to Redis
}
}
public class UserMapper
{
protected UserStorageStrategy _storageStrategy;
public UserMapper(UserStorageStrategy storageStrategy)
{
this._storageStrategy = storageStrategy;
}
public User findById(int id)
{
return this._storageStrategy.findById(id);
}
/* other methods */
}
Your strategy looks awfully like the mapper class, itself. It may make sense to make your mapper and user objects into interfaces, instead, and then your specific implementations choose how/where to store them. The strategy approach makes sense if your UserMapper class does many operations that are also unrelated to storage and that do not need to change despite the difference in storage; but if all your UserMapper class does is the storage, then an interface and multiple implementations would be simpler.
You do not need any particular OOP Design Pattern. What you require is a interface that provide the functionality.
Then your different data storage should implement it. And then you just need a strategy that provide the expected instance for the work flow of your program.
I'd make UserMapper an interface with multiple implementation concrete classes first and call the interface UserDao.
I'd call the implementation classes User{Mysql|Redis|etc}DAO. If you find any common piece of code between them it could be extracted into a common abstract base class.
At that point the logic of UserMapper class could be called to UserDaoResolver, that chooses and returns the concrete implementation upon some input or if you use some dependency injection framework (like Spring) you can delegate that function to it.
The current UserMapper caller would use the DAO implementation through its interface and obtain it by one of the method mentioned above.
I have a dilemma regarding the design of my code.
First of all, I am converting a VB to Java system.
The VB program has a class module which is like a combination of POJO and access the database for its logic. I created a similar class in JAVA with getters and setters. My dilemma is that since I need to copy the structure of the VB codes (we are forced to), I also need to include the query services in my JAVA class. But in our framework, only service classes have access to the query services.
I am thinking of changing my JAVA class to an abstact class, and use Anonymous class instead.
Sample:
public abstract class MyClass {
private int a;
private int b;
public String calculate1() {
// do processing for variables a and b
String sql = "" // build sql here
List<Map<String, Object>> result = query(sql);
}
public String calculate2() {
// do processing for variables a and b
String anotherSql = "" // build anotherSql
List<Map<String, Object>> result = query(anotherSql);
}
protected abstract List<Map<String, Object>> query(String sql);
// getters and setters for a and b
}
public class MyService {
#Autowired
private QueryService myQueryService;
public void execute() {
MyClass myClass = new MyClass() {
#Override
protected List<Map<String, Object>> query(String sql) {
return myQueryService.executeQuery(sql);
}
};
}
}
A few things to consider:
My Service is a singleton-scope bean.
I also like MyClass to be session based (1 instance per user).
Since I wont be declaring the MyClass in my Spring context, it cannot use dependency injection and cannot use other services. I will be saving the instance in a session and will just be retrieving the instance of MyClass.
Also because of this dilemma, I am forced to use string queries and JDBC template. Originally, our framework uses DAO objects and Hibernate. If someone also can solve the code using DAO, that would be better. If I will be using DAO objects, I would have to use different DAO objects with their DAO service classes.
I am not entirely sure if this is a good design. I don't know also if this will work. I was not able to run this in my environment.
I would really appreciate it if someone can enlighten me.
Thanks!
Since an instance of MyClass can't function without an instance of QueryService, how about you just pass an reference to the query service into the constructor of MyClass:
public abstract class MyClass {
private final QueryService queryService;
public MyClass (QueryService queryService) {
this.queryService = queryService;
}
protected List<Map<String, Object>> query(String sql) {
return queryService.executeQuery(sql);
}
}
public class MyService {
#Autowired
private QueryService myQueryService;
public void execute() {
MyClass myClass = new MyClass(myQueryService);
}
}
Making the queryService instance field final, and having such a constructor, clearly expresses this dependency in code.
I'm still quite new to Spring, and I've found it to irritating making all these CRUD DAOs, so I've made a "public class GenericCRUDDAO extends HibernateDaoSupport implements CRUDDAO". In my service objects I then simply say something like
private GenericCRUDDAO<User, Integer> userDAO = new GenericCRUDDAO<User, Integer>();
and no more do I have to write simple DAOs and wire them up. Yay! Except for one thing I'm sure all you experienced Spring developers see right away: I cannot get the Hibernate template inside the GenericCRUDDAO, so doing
HibernateTemplate ht = getHibernateTemplate();
gives me a ht that is null. Not so good. I thought of wiring it in, meaning making a genericCRUDDAO bean and then setting a static AnnotationSessionFactoryBean, but that still wouldn't give me a HibernateTemplate. Any suggestions on how I work around that so that I can have my Hibernate Template?
Any more issues with making a generic CRUD DAO I should be thinking about?
Cheers
Nik
For many, HibernateTemplate and HibernateDaoSupport are on the outs, and instead injecting a SessionFactory is preferred. Not everyone, mind you, but it is a trend, which I adopted not too long ago, removing HibernateTemplate from my own generic DAO.
This blog has a pretty good summary.
The author's examples should be able to help you get to where you want to be.
GenericDao
Well, to me, if your GenericDAO is 'generic', then you might need only one instance, and do all with that single instance.
I'm sure it doesn't bother you to wire on instance, it's at the repetition that you get mad (and I agree with you).
For example, you could pass the Entity class to a generic method.
public void save(Class, E...) : lets you save one or more instances of E type, E being one of your entities.
public E load(Class, Long id) : loads an entity.
...
/** Assuming the entities have a superclass SuperEntity with getIdent(). */
public class GenericDaoImpl implements GenericDao {
/** Save a bunch of entities */
public void save(SuperEntity... entities) {
for(SuperEntity entity : entities) {
getSession().save(entity);
}
}
/** Load any entity. */
public <E extends SuperEntity> E load(Class<E> entityClass, Long ident) {
return (E)getSession().load(entityClass, ident);
}
// other generic methods
}
Variant
In our applications, we actually have a variant for this. Because we have many specific request for each Dao, we need the specific Dao classes anyway (create the class and wire it), so to avoid the special case of a Dao that would not be defined, we make the specific Dao classes right away.
Coding
But in no way we repeat the code. All our Daos extends the GenericDao, providing in the constructor the Class parameter that is needed. Sample code (not complete, simple to get the basic idea):
public abstract class GenericDaoImpl<E extends SuperEntity>
implements GenericDao<E> {
/** Available for generic methods, so it is not a parameter
* for the generic methods. */
private final Class<E> entityClass;
protected GenericDaoImpl(Class<E> entityClass) {
this.entityClass = entityClass;
}
// generic implementation ; can be made efficient, as it may
// send the orders as a batch
public void save(E... entities) {
for(SuperEntity entity : entities) {
getSession().save(entityClass, entity.getIdent());
}
// possibly add flushing, clearing them from the Session ...
}
// other generic methods
}
public class PersonDaoImpl extends GenericDaoImpl<Person>
implements PersonDao {
/** Constructor, instanciating the superclass with the class parameter. */
public PersonDaoImpl() {
super(Person.class);
}
/** Specific method. */
public List<Person> findByAge(int minAge, int maxAge) {
//....
}
}
Wiring
Wiring all the beans is not a fatality. Nowadays, there are many autowiring policies, you don't have to worry about it. See them in Spring
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config
I'm using Hibernate. The question is at the bottom.
The current strategy
It's simple.
First of all, I have a basic Dao<T>.
public class Dao<T> {
private Class<T> persistentClass;
private Session session;
public Dao(Class<T> persistentClass) {
this.persistenClass = persistentClass;
this.session = HibernateUtil.getCurrentSession();
}
It's nice as a base class and it passes the most common methods up to its Session.
public T get(Serializable id) {
#SuppressWarnings("unchecked")
T t = (T) this.session.get(this.persistentClass, id);
return t;
}
protected Criteria getCriteria() {
return this.session.createCriteria(this.persistentClass);
}
When there's need to use queries on the model, it goes into a specific DAO for that piece of model, which inherits from Dao<T>.
public class DaoTask extends Dao<Task> {
public DaoTask() {
super(Task.class);
}
public List<Task> searchActiveTasks() {
#SuppressWarnings("unchecked")
List<Task> list = (List<Task>) this.getCriteria()
.add(Restrictions.eq("active", true))
.list();
return list;
}
}
This approach has always worked well.
However...
However, today I found that many times an instance needs reattachment to the Session and a line similar to the following ends up happening:
new Dao<Book>(Book.class).update(book);
... which I find to be bad, because
I don't like specifying the redundant Book.class
If ever a DaoBook arises, this construct will become obsolete.
So I turned Dao<T> into an abstract class, and went on to refactor the old code.
Question
In order to remove the Dao<T> references from the codebase, I thought of two approaches:
Create specific DAOs for every class that ever needs attachment, which would generate many almost empty DaoBooks and the sort.
Create a class that owns a Dao<Object> and exposes only the attachment methods (i.e. save(), update() etc).
I'm tending to go with #2, but I thought this "AttacherDao" pattern might be bad, so I'd like your opinion.
Any cons for #2? Also, do you find anything wrong with "the current strategy"?
Our approach is to have a DAO object (derived from a commonDao) for each persistent class. In fact we define interface for this DAO class and each DAO decides which interfaces are opened up.
Using the following code, user cannot delete the PersistentClass.
interface PersistentClassDao {
void save(PersistentClass persistentObject);
}
Class PersistentClassDaoImpl extends CommonDao implements PersistentClassDao {
void save(persistentObject) {
persist(persistentObject);
}
Even though it has some additional overhead, this approach helps in unit testing appropriate code before exposing an interface.
We've chosen an approach similar to lud0h's, with the following twist:
abstract class<T extends IModelObject> JdbcCrudDao<T>{
void create(T dbo){}
T findByFoo(String foo){}
void update(T dbo){}
void delete(T dbo){}
}
class BarDao extends JdbcCrudDao<Bar>{
}
But, the twist is that we selectively expose methods on the Dao through a facade and forward only those we absolutely must.
class BarController implements IController{
private static final BarDao dao;
// ...
void update( IBar bar ){
dao.update(bar);
}
}
The only short-coming in all this is it requires some casting about if you wish to hide your database keys behind an interface type (which we do), but it's a pretty minor inconvenience versus the alternative (database code outside of the Daos).
Couple of questions
Are you frequently creating your DAO to do a single task or are these long lived?
What about using a static function? Clearly your Book object can be bind the DAO function to without the Book.class reference...
Otherwise, I'm a little worried about keeping the session object around instead of fetching whatever the current session is - isn't it considered "bad" to have long lived session objects? I'm not a master of DAO, so maybe I'm missing something here.