Naming classes that query a database - dao

I know about the DAO pattern, but a DAO is meant for persisting entities, not for performing complex queries. People also often suggest that DAOs only query a single table, using multiple DAOs at the service layer to construct a complete entity.
But what about more complex queries, like a query that searches for specific entities and returns a list of Ids? How do i name classes that perform this kind of queries? I have seen classes that were named something like QueryManager which is horribly generic.
Is there a pattern for this kind of query-classes, or should i just name them something like EntitySearcher (where entity would be replaced by the actual entities name)?

Related

Is it plausible to uswe spring-data-jdbc in a scenario where the DB-schema differs from the domain-model

I'm considering using spring-data-jdbc for a project.
But i don't have any control over the DB-schema.
My domain model can be populated by the existing tables, but they differ in many ways.
Examples:
A specific aggregate in my model consists of nested Value-Objects. The corresponding table only features flat columns, so the nested Value-Objects would have to be mapped manually.
One the other hand, there are aggregates that don't have many nested Value-Objects, but the corresponding tables are organized according to a star-schema, so the values are distributed over many tables (instead of a single one).
I guess this prevents me from using many of the Quality-Of-Life features (like Query-Derivation and Mapping).
Do I actually get anything significant out of spring-data-jdbc in comparison to using a plain JdbcTemplate in this scenario?
The scenario you describe would make me tend towards plain JdbcTemplate.
But I would consider using the Aggregate approach Spring Data JDBC does:
Load complete aggregates
Reference between aggregates using ids, or something like an AggregateReference
And if you have an aggregate that actually can be mapped using Spring Data JDBC you can still do that.

Onion Architecture using JPA Entity as Domain Entity

I've been struggling to choose to work with JPA entities as separated classes than domain entities in a single bounded context. I've faced the following choices
Use separated domain classes for Aggregate roots/Aggregates..etc with domain repositories to wrap Spring JPA repositories and use converters to map JPA entities <> Domain Entities with only required data
Lazy loading is about to be given away unless in mappers/converters are handling this inside domain repositories but this is overkill.
When saving objects, there might be related Aggregate roots (one to many relationship) which later in complex logic, I had to extremly take care of the state of the Domain entity to pass it to the domain repository and either fill it with all related data or simply map it (another method in the converter) with out relationship data (cascading not applied on JPA persisting)
A lot of duplicated code to avoid such situations even for very simple use cases
Or Use JPA entities as my domain entities and so far there are multiple examples/opinions of this like
https://github.com/citerus/dddsample-core/tree/Spring_Annotations_Autowire
http://www.javamagazine.mozaicreader.com/MayJune2018/Twitter#&pageSet=50&page=0
Should JPA entities and DDD entities be the same classes?
DDD, domain entities/VO and JPA
How to implement DDD using Spring Crud/Jpa Repository
On the other hand, there are opinions like this
Is it a good practice to use JPA entities as domain models?
My question, on the long run, from experience
What would cost more effort & time ?
Are both approaches are acceptable as practices ?
What are the pros and cons of both ?
What would cost more effort & time ?
Decoupling almost always does. It's trade-off !
Are both approaches are acceptable as practices ?
Yes. I see there are many conflicted opinions on both approaches but really, they're just opinions. Both are applied and cost.
What are the pros and cons of both ?
Using JPA entities as domain entities approach really 1- reduces the time cost notionally. 2- Also lets you use lazy loading with relationships avoiding more code in application service, that if you're not following referencing other aggregates by id instead which also is opinion based but really costs the lazy loading of JPA.
One down side to this approach is unit testing as I see it. Unit test should not depend on starting up container, database...etc. Should purely test business logic. But that's not optimally possible with such frameworks. See this answer for example
JPA Entity must be unit tested and how?
Using JPA as separated entities in the infrastructure with wrapper repositories will make unit tests easier to mock data and test purely the domain (business rules) with comfort. It will reversely to the previous pros, cost you the mapping effort and time, too much duplicated code for mapping, wrapping repositories..etc. It brings the headache (and this should be a pro) of caring what is the state of your domain entity because mapping of nulls to JPA entity will effect the relationships mapping to your persistence source, and you REALLY SHOULD CARE for the state of your domain entity.
Also automatic lazy loading of ORM will not be used and done easily. Either
1- You put a reference to other aggregates as member in your aggregate root (Breaking the aggregate ID reference rule) and handle that in the mappers
2- You get from repository only wanted data of aggregate root with other aggregate's ID as reference members. This is done by well defined queries in the repository implementation so, this is a lot of writing & customizing queries. Avoiding using default ones which returns full JPA entities with ready lazy loading related references.

jpa specification query method

We are using the Spring Data JPA for database access. Our repositories contain basic query methods. What we want to do now is to use the Specification-Interface (criteria API) combined with complex query methods (like findByName(Specification spec)). The problem is that these two ways block each other out (since there are two where queries now). Is there any way to do this, like telling JPA to combine the two where parts with AND? The reason we want to do this is because some parts of the where query are essential for every query. They should be defined in the name of the query method. The Specification only should contain individual criterias for individual use-cases.
Or is there any other way to solve this?
Currently this is not supported. Please feel free to raise a JIRA issue if you think this would be a worthwhile enhancement.

Ditching ActiveRecord and NHibernate -- how to rearchitect?

I have an MVC3 NHibernate/ActiveRecord project. The project is going okay, and I'm getting a bit of use out of my model objects (mostly one giant hierarchy of three or four classes).
My application is analytics based; I store hierarchial data, and later slice it up, display it in graphs, etc. so the actual relationship is not that complicated.
So far, I haven't benefited much from ORM; it makes querying easy (ActiveRecord), but I frequently need less information than full objects, and I need to write "hard" queries through complex and multiple selects and iterations over collections -- raw SQL would be much faster and cleaner.
So I'm thinking about ditching ORM in this case, and going back to raw SQL. But I'm not sure how to rearchitect my solution. How should I handle the database tier?
Should I still have one class per model, with static methods to query for objects? Or should I have one class representing the DB?
Should I write my own layer under ActiveRecord (or my own ActiveRecord-like implementation) to keep the existing code more or less sound?
Should I combine ORM methods (like Save/Delete) into my model classes or not?
Should I change my table structure (one table per class with all of the fields)?
Any advice would be appreciated. I'm trying to figure out the best architecture and design to go with.
Many, including myself, think the ActiveRecord pattern is an anti-pattern mainly because it breaks the SRP and doesn't allow POCO objects (tightly coupling your domain to a particular ORM).
In saying that, you can't beat an ORM for simple CRUD stuff, so I would keep some kind of ORM around for that kind of work. Just re-architect your application to use POCO objects and some kind or repository pattern with your ORM implementation specifics in another project.
As for your "hard" queries, I would consider creating one class per view using a tiny ORM (like Dapper, PetaPoco, or Massive), to query the objects with your own raw sql.

LINQ - which layer should LINQ typically fall into, DAL?

just wanted to gather different ideas and perspectives as to which layer should (and why) LINQ fall into?
LINQ = Language INtegrated Queries. This is the query extensions that allows you to query anything from databases to lists/collections to XML. The query language is useful in any layer.
However, a lot of people refer to LINQ to SQL as just "LINQ". In that context, a combined BLL/DAL makes sense when you're using L2S and that's where you do LINQ queries against your database. That does of course not exclude doing subsequent queries against the results from those same queries in new (Linq to objects) queries in higher layers...
it depends on what you want to do with linq. when using linq2sql i`d recommend the DAL, but Linq is more than just database access. you can use it to manipulate lists, ienumerables of business objects and so on... Linq itself can be useful everywhere in your application.
I consider your DataContext-derived object to your DAL layer itself, and LINQ is just a very flexible interface to it. Hence I use LINQ queries directly in the Business layer.
Both. DataContext is the DAL and, when using the designer, the auto-generated partial classes that map on to SQL objects (tables,views) can be considered part of your business layer. I implement partial classes that implement some of the partial methods to enforce validation and security as needed. Some business rules don't map directly on to DB objects and are handled via other classes.
I think if you are doing Linq to Sql, you should always do it in your DAL. However if you are doing Linq to Objects where you are just filtering, playing with different object you can do that is BL layer.
I think LINQ should be the very lower-level (DAL) and I think it should be wrapped into a BLL.
I know a lot of people like to use the partial accessibility of the models that LINQ to SQL generates but I think you should have clear separation of interests (see what I did there?). I think if you're going to have business logic it needs to be decoupled completely from your data access logic.
I think what makes it tricky is the fact that you can keep chaining those LINQ extension methods anywhere you have a using System.Linq line in your code. Again though I think LINQ belongs with the definition and should be at the lowest possible level. It also makes TDD/Unit Testing much, much easier when you wrap the usage of LINQ in a BLL.
I use linq in the traditional 'data access layer' or in 'data access objects'. This allows modularization of code, promotes data code in one place (vs cutting and pasting the same code a few different places) and allows a different front end to be developed with relative ease.
It depends on the architecture of your application, and it makes a huge difference how much the presentation model matches the data model. I agree with separating out business logic operations from the data objects and access methods created by LINQ. I also tend to wrap all data-level operations inside a manager class so I can make the data context an internal class.
I think the point of Linq is that it replaces your DAL.
The equivalent to your old DAL is all the auto-generated code behinf the DBML files + anything extra that Linq can't do added by you.

Resources