i want to do CQRS. where should i put queries? currently i can think of two options:
1) each query should be an independent class that contains just a string? and such object should be passed to simple/stupid repository
in this approach we have potentially thousands of small queries/classes. also we have problems with complex queries (e.g. in oracle we can't have empty where in (...) part) so there is no good place to check if that part is empty and simply return empty collection without even touching database
also it's a bit hard to use different queries when working on different databases
2) create 1 method per query in repository object
is it still CQRS? don't we loose the ability to easily select and pass query? or maybe it's not really needed?
I think you may be mixing concepts here. CQRS only states that there are separate models for query and commands, which is really broad.
For instance, one possible implementation is having two separate generic repositories, one for queries and the other for commands. Query repository implementations may use a database while command repositories implementations may use a different one. Or not.
Passing query classes to your repository versus having your repository implement many different methods is just a matter of organizing your (query) repository, not a command-query segregation concern.
Related
There is a pattern of making a DAO interface before DAO implementation. I googled the advantages of this pattern and one striking point was to support multiple databases.
Now, what i could understand is that multiple databases here means different database engines rather than multiple datasources. Obviously multiple datasources should not have affect on how DAO implementations are made out of DAO interface.
My question is what can be the situations where we may need to support multiple database engines catering the same data? Also if such need arises, how will the REST endpoints be managed to support different databases?
Will they be like for e.g. /db1/courses/, /db2/courses ? Do correct me if i have made any wrong assumption or statement in this question.
I just wanted to add my answer to this about beginning Spring development. This is one of the things that initially will not make sense at first. You will end up asking yourself:
There will be only 1 database, so this doesn't make sense why do it?
Why would I define an interface when there will only ever be 1 implementation?
But really neither of these are really why you do this. But it is the convention and pattern and this style is just what people are use to and you will like it better overtime. There are some other reasons too:
Spring Data - this is an alternative to using an entity manager, whereby you only define interfaces and Spring will actually create beans which implement your repository functionality for you.
Design - ensuring you define an interface will help keep your repository a repository.
Easier Mocking - although arguably you can still do this in Spring without needing to define an interface it is still a bit cleaner when you want to replace the implementation with another.
But really it is just the Spring way, people will find it easier to understand your code if you do this.
I came across this situation where I had to check two DBs and get the data. The other DB was a back up one.
So this was the flow.
RestController --> Service --> DBService
--> DB1Repository --> Connect to DB1
--> DB2Repository --> Connect to DB2
We can design as we want, all it matters at the end is that we follow SOLID principles.
Basically the high level components should not depend on the low level components, but both should depend on the abstractions.
Ill pop in here to describe a real world example.
We recently wanted to change out a large production database (Oracle) to a different one (SQL Server).
For different areas of the database, we had different DAO interfaces and implementations. For example, CustomerDAO, AccountsDAO, etc.
For each interace (like CustomerDAO) we had an implementation (CustomerDAOImplOracle).
It was relatively straight forward for us to write SQL Server versions of the DAO's (the SQL syntax and jdbc libraries were of course different) and swap them over with minimal changes to our business logic (the services which use the DAO's).
So, CustomerDAOImplOracle was reimplemented at CustomerDAOImplSQLServer. And so on...
What we learn:
Interfaces provide good abstractiuon and allow for multiple implementations
The DAO layer allows us to "switch out" the database (or its client libraries) if necessary
Hiding implementation details of the database from the business logic reduces coupling and complexity
In our code base we make extensive use of DAOs. In essence a layer that exposes a low level read/write api and where each DAO maps to a table in the database.
My question is should the dao's update methods take entity id's or entity references as arguments if we have different kinds of updates on an entity.
For example, say we have customers and adressess. We could have
customer.address = newAddress;
customerDao.updateCustomerAddress(customer);
or we could have
customerDao.updateCustomerAddress(customer.getId(), newAddress);
Which approach would you say is better?
The latter is more convenient since if we have the entity we always have the id, so it will always work. The converse is not always the case though, but would have to be preceded with getting the entity before performing the update.
In DDD we have Aggregates and Repositories. Aggregates ensure that the business invariants hold and Repositories handle the persistence.
I recommend that Aggregates should be pure, with no dependencies to any infrastructure code; that is, Aggregates should not know anything about persistence.
Also, you should use the Ubiquitous language in your domain code. That being said, your code should look like this (in the application layer):
customer = customerRepository.loadById(customerId);
customer.changeAddress(address);
customerRepository.save(customer);
I assume your question is
Which approach of the two is better?
I would prefer the second approach. It states clearly what will be done. The update object will be freshly loaded and it is absolutely clear that only the address will be updated. The first approach leaves room for doubt. What happens if customer.name has a new value aswell? Will it also be update?
I have an application that has the following java files:
Services:
AccountService.java
UserService.java
MessageService.java
DAOs:
AccountDAO.java
UserDAO.java
MessageDAO.java
Tables:
ACCOUNTS
USERS
MESSAGES
In MessageService.java, I have a function newMessage() that has to query data from all the 3 tables.
(1) According to Spring's decoupling standards, this is how the calls should be made:
AccountDAO.java -- ACCOUNTS
/
MessageService.java -- MessageDAO.java -- MESSAGES
\
UserDAO.java -- USERS
But the problem is, this approach makes 3 DB calls.
(2) For better Performance, I would do:
MessageService.java -- MessageDAO.java -- Join ACCOUNTS, MESSAGES and USERS
But this way, it's tightly coupled and if there's a change in USERS table, I'll have to change MessageDAO.java (and all other DAOs that I have, that use the USERS table) too. That is really bad, since (in the non-hypothetical) we have a LOT of DAOs
Which approach is considered a better practice? Or is there another approach that I'm missing?
According to Spring's decoupling standards, this is how the calls should be made
This is false. There are no "decoupling standards" with Spring. Please find me a reference in the Spring documentation that tells you how you must structure your persistence layer code.
Typically, you would have one DAO for each "entity" that your application wants to operate on, but it would be foolish to take this pattern to the extreme of deconstructing a query that joins multiple tables together into three distinct queries.
If you need to have a newMessage() method that joins some tables together in a query, choose which DAO that makes the most sense in - probably the MessageDAO and write the query/method in the way that makes sense.
But there is no rule saying that you must have distinct queries for each entity and that one DAO class is not allowed to make queries that touch the tables of other entities. This is too extreme and has no benefit.
If one the other hand you are worried about the maintainability of having multiple data layer classes that are aware of all of your tables, then look into an ORM solution as parsifal mentioned to alleviate some of this work.
The alternative is to use an ORM such as Hibernate, mapping each of your tables to an entity. Then define the logical relationships between those entities. For example, a 1:M relationship between users and messages. As your tables change, your mappings will need to change, but your SQL won't (because Hibernate will generate it).
For most relationships, Hibernate is very good at creating joins to retrieve related entities in one query. You can control whether this happens; I recommend using lazy loads as a default for most relationships, and switching to eager loads as-needed.
Doing this as 3 separate queries might impact correctness if the data might change between one query and the next. Don't let (your idea of) Spring's guidelines make you write code that gets the wrong results.
It sounds like a join in SQL is the right approach.
Whichever method you follow, it's always about finding a sweet spot between decoupling and performance. It holds with even the selection of number of layers, etc.
So I guess as #mattb recommended, it's completely fine to join tables in a DAO if it makes sense in the particular context
We're going to write a new web interface for a big system based on Oracle database. All business rules are already coded in PL/SQL stored procedures and we'd like to reuse as much code as possible. We'll write some new stored procedures that will combine the existing business rules and return the final result dataset.
We want to do this on the database level to avoid java-db round trips. The interface layer will be written in Java (we'd like to use GWT), so we need a way of passing data from Oracle stored procedures to Java service side. The data can be e.g. a set of properties of a specific item or a list of items fulfilling certain criteria.
Would anyone recommend a preferable way of doing this?
We're considering one of the 2 following scenarios:
passing objects and lists of objects (DB object types defined on the
schema level)
passing a sys_refcursor
We verified that both approaches are "doable", the question is more about design decision, best practice, possible maintenance problems, flexibility, etc.
I'd appreciate any hints.
I would recommend sticking with a refcursor with well defined keys (agreed on both sides by java devs and pl/sql developers). This is much easier to extend in the future, you can easily convert the refcursor to hashmap and then a hashmap to a POJO using a apache bean utils if needed. I'm working on a big telecom project with many approaches to this issue and refcursor seems to be the best at the end of the day.
In the past I have achieved exactly the same with classic JDBC CallableStatement without any perfomance or maintenance issues. With ORM solutions like Hibernate making persistence much more flexible, you can wrap your solution around Hibernate as achieve in this post. Also see this example if you are not already familiar with the way store procedure and CallableStatement works.
It's been a while since I've done something like that, but the way I remember is that you need to define a view that calls your stored procedure, and you can then easily read the result sets from within java, with the OR-mapper of your choice.
So, this seems close to your scenario 1, which never caused any problems in my experience.
The one thing one needs to be careful is transaction handling: If your stored procedures write data, and you call several of them within a Java EE transaction, you might get into a situation of data inconsistency.
How should one go about filtering a series of domain objects according to user-defined criteria? Should the filtering methods be in the model or should they be in the DAO?
If you want to use your model objects only (mainly) as data containers you should put the filter into the DAOs you are already using. It is a good practice to make sure, that the user defined criteria are database independent (so pass your own filter object instead of plain e.g. Hibernate Criteria. query by example may work great, too).
Then your DAO methods can look like this:
public interface BeanDao
{
List<Bean> findAllByFilter(BeanFilter filter);
}
The choice of whether to retrieve a greater number of objects and then filter or simply to retrieve the correct objects in the first place depends on the underlying data. Most applications will use a combination of the two.
The things I would consider are:
Network bandwidth & Memory requirements
If after filtering there are a small number of results but a significantly larger number of results before filtering then it could be a waste of bandwidth and memory resources to do the filtering in code.
Query speed
Filtering the results in the database can be more expensive than doing the logic in code - disk vs memory. Indexes are required to make it worthwhile.
Maintainability
Creating new queries can be time consuming. It will definitely mean writing some sql and revisiting various phases of testing. It may require modifying the db schema such as adding an index to speed up the query.
When solving this problem in Java it might be worth considering the visitor pattern. I often use two interfaces SingleMatcher and MultipleMatcher to filter a collection of objects. Implementations of these can be combined to create new user-defined criteria. Another advantage of this is that once you have a the matchers users may want to use you won't have to go back to testing to create new criteria.