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) {...}
}
Related
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;
}
I hear that in Java I can achieve polymorphism through injection at runtime. Can someone please show a simple example of how that is done? I search online but I can't find anything: maybe I am searching wrong. So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
in such case I am achieving polymorphism twice: MyClass is at once of type Parent and Naming. But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection. I hope the question is clear. Thanks.
So the end result here, per my understanding, is to change the behavior of a method through injection instead of by #Override it during development.
So I know about polymorphism through interface and and extension such as
class MyClass extends Parent implements Naming
This is known as inhertiance and not polymorphism. MyClassis a Parent and MyClass is also a Naming. That being said, inheritance allows you to achive polymorphism.
Consider a class other thanMyClass that also implements Naming :
class SomeOtherClass implements Naming {
#Override
public void someMethodDefinedInTheInterface() {
}
}
Now consider a method that takes a Naming argument somewhere in your code base :
public void doSomething(Naming naming) {
naming.someMethodDefinedInTheInterface();
}
The doSomething method can be passed an instance of any class that implements Naming. So both the following calls are valid :
doSomething(new MyClass());//1
doSomething(new SomeOtherClass());//2
Observe how you can call doSomething with different parameters. At runtime, the first call will call someMethodDefinedInTheInterface from MyClass and the second call will call someMethodDefinedInTheInterface from SomeOtherClass. This is known as runtime-polymorphism which can be achieved through inheritance.
But I don't get how injection works. The idea is that I would not be using the #Override keyword during injection
That's true in the broader sense. To inject something into a class, the class should ideally favor composition over inheritance. See this answer that does a good job in explaining the reason for favoring composition over inheritance.
To extend the above example from my answer, let's modify the doSomething method as follows :
public class ClassHasANaming {
private Naming naming;
public ClassHasANaming(Naming naming) {
this.naming = naming;
}
public void doSomething() {
naming.someMethodDefinedInTheInterface();
}
}
Observe how ClassHasANaming now has-a Naming dependency that can be injected from the outside world :
ClassHasANaming callMyClass = new ClassHasANaming(new MyClass());
callMyClass.doSomething();
If you use the Factory pattern, you can actually chose which subclass gets instantiated at runtime.
Do you think we could have done what we did above using inheritance?
public class ClassIsANaming implements Naming {
public void doSomething() {
someMethodDefinedInTheInterface();
}
#Override
public void someMethodDefinedInTheInterface() {
//....
}
}
The answer is No. ClassIsANaming is bound to a single implementation of the someMethodDefinedInTheInterface method at compile time itself.
`
Taking a contrived example. You have a class Store that stores things:
class Store {
private List l
void store(Object o) {
l.add(o);
}
void setStoreProvider(List l) {
this.l = l
}
}
You can inject the actual List used as the backing storage using setStoreProvider which could be a linked list, array backed list, whatever.
Hence, depending on the injected type your Store class would have the features of the injected type (with regards to memory usage, speed, etc).
This is a kind of polymorphism without the class implementing an interface.
Persistent object:
#Entity
public class PersistentModelObject{
...
}
I need something like:
interface GenericDao<T annotated_with Entity>{
//crud
}
Or can it be simulated in some way (with extension, implementation, etc).
EDIT: Please someone who understands my question to edit it to some understandable level.
I dont think you can use annotations like that via generics, but you can use java.lang.Class java.lang.reflect.Field isAnnotationPresent(YourAnnotation.class) to check if a class is annotated with a certain annotation.
A better aproach might be using marker interfaces? Something like:
public class PersistentModelObject implements MyPersistableType{
...
}
and
interface MyPersistableType {} //marker interface
Then you may use it like this:
interface GenericDao<T extends MyPersistableType>{
//crud
}
But then again, it depends on what you are trying to solve.
This restriction can only be checked at runtime using reflection.
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.
I've got the following classes set up:
public abstract class Process<T,S> {
...
}
public abstract class Resource<T, S extends Process<T, S>> {
protected S processer;
...
}
public class ProcessImpl<EventType1, EventType2> {
...
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
processer = new ProcesserImpl();
...
}
Everything is fine until I get to the ResourceImpl. I'm told that ProcessImpl is not a valid substitute for the bounded parameter <S extends Process<T,S>> of the type Resource<T,S>.
I've tried various ways of getting around this and keep hitting a wall.
Does anyone have any ideas?
public class ProcessImpl<EventType1, EventType2> {
...
}
Because ProcessImpl doesn't extend Process. Your ProcessImpl is not derived from Process, which is what you're declaring that parameter should be.
You might want to do something like this:
public abstract class Process<T, S> {
}
public abstract class Resource<T, S extends Process<T, S>> {
S processor;
}
public class ProcessImpl extends Process<EventType1, ProcessImpl> {
}
public class ResourceImpl extends Resource<EventType1, ProcessImpl> {
}
If you constrain the S parameter of the Resource to be a processor you also need to properly declare it on the ProcessImpl class. I don't know what EventType2 is but it should be implementing Process interface. I assumed you actually want to say ProcessImpl.
I can't see a way to edit the original version, or comment on given answers without a better rep.
This code will exist on a web layer, the eventtype2 is defined on the persistence layer and accessible only in the core layer which exists below this level.
So unfortunately without having a tight coupling, which I would like to avoid, I don't have access to EventType2.
If you don't want your code to depend on some existing package, which contains the Process, you could also introduce some new interface package depending on nothing in the very bottom of the class hierarchy. (If you are able to change the constrains of the inheritance of course.)