Spring Data JPA - How to Combine Multiple and and or Through Method Name

JPA: Correct way to use Service and multiple Repositories

Services don’t always have to be transactional, but when you’re doing database work with JPA transactions are extremely important, because transactions make sure your changes get committed predictably without interference from other work going on concurrently. Spring makes it easy to make your services transactional, make sure you understand transactions so you can take full advantage of them.

You can use services within services, you can set up transaction propagation so they both use the same transaction or they can use separate transactions, there are valid cases for either of these. But I would suggest not doing what you’re doing here.

A service is a place you put business logic, especially business logic that you need to be transactional (all-or-nothing). It makes sense to organize your logic into services according to function, so that the service methods are actions taken by users playing some particular part.

But having a service for each type of entity isn’t really useful and I’d recommend against it. A service can have any number of repositories, you don’t have to wrap each one in its own service. (Tutorials show entity-specific services, or they may skip the service layer altogether, that’s because they want to show you framework features, and minimize the business logic. But real applications tend to have a lot of business logic.)

One problem with what you’re doing with entity-specific services: calling them in the controller one after the other means each one uses its own transaction. Creating transactions is slow and having separate ones opens you up to possible data inconsistencies. Having your business logic within one transaction limits your exposure to consistency issues to just those associated with your transaction isolation level.

Also I disagree with the idea that services should be converting between dtos and entities. Once in a while you may find a need for a dto but it shouldn’t be routine. For web applications that use JSP or thymeleaf you may be able to happily add entities as request attributes and let the template use them directly. If your controllers need to return JSON, you may be able to hook up a messageconverter to generate JSON directly from the entity or it may be better to have a dto. Try to keep the focus on implementing business functionality and avoid moving data from one kind of holder into a different kind of holder, because that kind of code is brittle and error-prone.

For differences between controllers and services I have answers here and here.

Java Spring Boot, Join tables in type safe way without plain strings

It is "type-safe" - because they all are strings.

Your problem is: If someone use the "wrong" referenced field, then it will not checked at compile-time.

This is true and cannot be changed, but you can check it at runtime.

Or even better: Spring/Hibernate can do that for you.

Just enable the hibernate validation by adding spring.jpa.hibernate.ddl-auto=validate to your application.yml or application.properties.

Now on the startup of spring you will get this exception (if you have a typo for address/adress):

Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: Address.user, referenced property unknown: User.adress

You can also use the other modes. Have a look to the documentation.

All modes (expect none) will validating the schema.

That's the best solution, since there are no compile-time-checks.

You can try using JOOQ also.

How to name methods in spring data with and-or in the same query

findByStatusIsAndSellerIdOrStatusIsAndBuyerId(status, id)

expects 4 parameters for the four conditions.

You also should never use a derived query with AND and OR because precedence gets pretty confusing at best.

So pick a name that you like and use a @Query annotation to specify the query to use.

SELECT x FROM X x where x.status = :status and (x.seller.id = :id or x.buyer.id = :id) should be close to what you need.

SpringData jparepository AND / OR operators

Like Slava Said, you should do:

@Query("from table t where t.propertyOne in :param1 and (t.propertyTwo like :param2 or t.propertyThree like :param3 or t.propertyFour like :param4)")
List<Table> findByParams(@Param("param1") List<String> param1, @Param("param2") String param2, @Param("param3") String param3, @Param("param4") String param4);


Related Topics



Leave a reply



Submit