Spring DAO class method - protected vs public? - java

In my Java Spring application I have a DAO class with methods. I would like to know which access modifier use: protected or public?
In which situation we should use protected modifier? I don't know when I should use a protected modifier, so I always use public. Is it proper way?

DAO layer is mostly used for database transactions. For eg: saving, updating, fetching, etc.
Now they don't have any business logic in them, because we put the business logic in the Service layer. Usually this Service layer makes a call to the DAO layer whenever it needs to perform a database related work.
Therefore, public should be used in most cases (as they are getting called from a different layer/package) all together.
Protected is good when you are sure that you will make call only from the same package(or sub classes), which may not always be the case. So no, protected is not recommended.

Protected doesn't really make sense for DAOs, since you need the methods in other packages, in classes which don't implement the DAO. Therefore public is almost always the way to go.

For DAO classes, you should make an interface with Dao methods declared(Which will obviously be public). Your DAO classes should extend the interface. In this way your Dao methods will be accessed from other classes via the interface reference.
It's the better way, because it will be easy to test. You can provide a mock implementation of the DAO interface to test your code. You can do this before you write your actual DAO class. If you are calling DAO methods with interface reference variable, then you can change your DAO class and it will still work because you are changing the class not the interface whose reference you are using for calling the methods(renaming class name for an example).
It's the important design principle that you should always code for interface wherever possible. I recommend you to see this answer to read about why you should code for interfaces in DAO.
You should use protected modifier in case of inheritance. When you want outside the package only child classes should be able to access the methods and properties of your class. when you need to do somethings that should not exposed in public API but still needs to be overriden by subclasses for example template method pattern.

Related

Singleton on method with Context parameter

I code CRUD methods and wonder if it's useful to define my DAO class as singleton. While they have as a parameter the context of the activity that requires them.
I do not try to do it because I learned about the net. And I notice that the singleton is used in the classes that manage a database outside the activities
I wouldn't use a singleton. It's a recognised anti-pattern, and makes testing difficult. I would much rather inject in a concrete implementation, and have your service reference a DAO interface (allowing you to inject different implementations in)
Basically I have a database with each table linking to a DAO class and a class that defines my table. My DAO class when I instantiate it I have in parameter the context to activate it. This makes it possible not to have calls from everywhere. Do I still need to implement a singelton?

Can a Spring #RequestMapping-annotated method be static?

This is a follow-up question to a previous question.
From what I understand, one #Controller-annotated class with #RequestMapping-annotated methods cannot successfully inherit from another because Spring can't recognize they're both mapping to the same method(s). Even if Spring recognized they were the same instance, it would have no way to decide which instance of the two controller beans to use to invoke the method.
But static methods are invoked independent of any instances of a class, and child classes do not carry their own copy of the parent's static members. Making all of my #RequestMapping-annotated methods static (at least on the parent class) could resolve this problem, which brings us to my question:
Can a public static method be used with #Controller on the class and #RequestMapping on the method? And would it behave about the same as a non-static method*?
* I know that a static method naturally can't access instance members, but controllers should typically be implemented in such a way that there aren't any instance variables anyway. All the methods I'm dealing with would work exactly the same if they were static methods, provided the framework allows for it.
It works fine for me in Spring 3.2.X. Though, controllers often have data members on their instances, but they're usually autowired instances that are services. So I wonder if you're misunderstanding the overall design pattern of the Spring framework.
I can't think of any real benefit in using a static method, the controller instance is already there, so even if you made the controller have all static methods it's still going to get instantiated. I would think the instance invocation overhead would be minuscule and lost in the noise as far as performance.

Multiple Inheritance in Java - Spring Data

I want to create a DAO class named BaseDAO that should have the JPA and JDBC capabilities in Spring. I mean, I want to extend JPADAOSupport and JDBCDAOSupport classes of spring in to my BaseDAO class. I am aware that multiple inheritance is not an option in Java.
I have created two separate Base classes like BaseJPADao and BaseJdbcDao extending the respective classes. Is it possible to have a single class to extend both? Is there any design pattern solving this issue. Please advise.
Why don't you have a DaoGateway bean having injected the actual JPA DAO and the JDBC DAO beans.
This gateway can then decide which DAO to delegate a given request (to JPA or to JDBC).
You should always favour composition vs inheritance when reusing functionalities.
no it is not. if it was possible, you would still have the same result as in
one class extending JPADAOSupport and JDBCDAOSupport, which you yourself say you know is not possible because multiple inheritance is impossible.
you can write to an interface, and provide two implementations, though.
This would be easy to do with delegation if they both had interface level access you want:
public class MyUberClass implements WhateverJPADAOSupportDoes, WhateverJDBCDAOSupportDoes {
private JPADAOSuport jpa;
private JDBCDAOSupport jdbc;
// now implement all methods specified by the interfaces on the class signature and delegate to their respective member
}
But it seems you want access to all of their public methods. As there is no interface for both you can do the same as above but it can't be of both types simultaneously. The language expressly denies you this.
Your only other option is to create an adapter interface that your code can rely on and then use the combination delegation. If you're hoping to have one class that you can just drop in as a substitution for both then the answer is you can't.

Checking if a method is an overridden method of Interface using reflection

I am trying to auto generate some EJB service code, which are wrappers around Java DAO classes. DAO classes implement DAO interfaces, but also have their own public methods. This DAO layer is implemented by another team, so I cannot play around with it.
I am using CodeModel API to generate the code. I get each DAO class and want now to create the EJB Service code. Using java reflection I am trying to check if the method declared in the DAO class is an overridden implementing method of the interface or not. Is there anyway in which I can check that?
1) If overridden methods are with #Overridden annotation, than you could iterate through these methods, and check their annotation using this API: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Method.html#getDeclaredAnnotations%28%29
2) If there are no annotations, I think, the only way is to iterate through parent classes and interfaces and compare method signatures, declared there with signatures in your class.

Best way to add annotations to inherited methods

I have a number of abstract superclasses from which my concrete class inherit various methods. Some of these methods need to have JPA or JAXB annotations placed on them in the concrete class. Currently I do this via the following:
#MyLocalAnnotations
#Override
public method inheritedMethodHere (yadda yadda)
{
super.inheritedMethodHere(yadda yadda);
}
Is there a way to do this without overriding the method? It seems like such a waste to override a method only to supply local annotations.
Unfortunately, there isn't a better way than what you are doing now. To do what you are describing you will have to override the method, considering that your JPA annotation will need information specific to the concrete class.
With JPA annotations, you actually have two options -- you can annotate the methods, or you can annotate the properties. On our project we've standardized on annotating properties rather than methods, but this won't help you either, as the properties are presumably part of the concrete class. (If they are somehow shared in the super-class, then you REALLY will need to annotate the methods, and override them).
Its hard to make a recommendation without seeing your schema, but if your entity classes have so much in common that they share many properties in the super-class -- might they simply be stored in the same table, perhaps with a differentiating type column?
Or alternatively if they are not nearly identical, might you just reproduce the common properties in each concrete class? You might be causing yourself more work rather than saving yourself by trying to capture the common properties in the super class. Since you will have to annotate them individually in the concrete classes, just declare them in the concrete classes. If you need common methods that interact with these properties, a separate Utility class to capture those functions could be the answer.
On our project we DO sometimes use a common super class for entities, but it captures some meta-data about the entity -- nothing that would impact persistence logic. Therefore, no JPA annotations are needed (nor would they make sense) in the abstract class.

Categories