Do I need entities if only getting data from db? - java

Hopefully easy questions:
If I have an application that is supposed to only get data from
database (it doesn't persist anything)?
Do I need an exact structure of db presented by set of
#Entity-annotated classes?
Do I need Entities at all anyway?
Or can I just use DAO and do something like:
ObjectFromDb ob = dao.find(someProperty);
given that ObjectFromDb is just a regular POJO without a single JPA
annotation?
I google'd it for a short while, but it seems to be too specific questions... Thanks for any advice!

You do not need entities for querying, but they can make your life easier.
You can use regular SQL for queries.
You can also have some entities defined, but query only for a subset of their data - i.e. a projection query.
You can also use JPA constructor command with projection queries to map directly to your result objects:
List<MyClass> dtos = em.createQuery("SELECT NEW com.example.MyClass( e.name, e.data) FROM Entity e").resultList();
EDIT: With annotated entities you can use features of JPQL that are not available in SQL, e.g. path navigation. Properly annotated entities can clarify the DB mapping.
An entity does not need to map all columns of a table, you can use any subset you like, as long as it includes the id.

Related

Is it really needed to use Spring Data JPA Named Queries?

After making some search on the web, I think that when using Spring Data JPA Named Queries, we need some extra implementation or definitions comparing to the derived or dynamic queries in Spring Data JPA. In this scene, I am really wondering that do we really need to use Spring Data JPA Named Queries?
Spring Data derived queries are intended (and useful) only for very simple queries. Those queries where you look at the name that you would naturally give such a method and would immediately know how to implement it in SQL or JPQL.
As soon as a query gets a little more complex we shouldn't use derived queries anymore, and often we can't even if we wanted to. For example query derivation doesn't have a way to control the precedence between AND and OR.
For all other queries we need to explicitly code the query one way or the others. And if you don't want your queries mixed with your repository, a named query is a very viable alternative.

Method names too long in Spring JPA

I am using Spring Data JPA. I am using normalized DB which means, to get a full details of what i want, i have to join many tables. As you know JPA generates method name based on query. But, due to multiple joins, my method name becomes so long. sometimes, its more than 250 chars.
I am looking for #query annotation with JPA methods instead of auto generated JPA method names.
I wanna know the performance implications if i use #query annotation?
Also, please suggest any alternatives to solve my long method names keeping performance into consideration.
Whenever you write your query using Spring Data (i.e List<MyObj> findAllByName(String name)) spring data actually generates your query the same way as you'd write it using #Query annotation. So, technically speaking, boot-up time will be quicker if you write your queries as HQL or JPQL within #Query annotation. The most performant way is of course to use native queries, but it can be a pain in the ass later in the game.

How to properly update entities using REST and JPA/Hibernate

I have entity Document, which has lots of columns, one-to-one, one-to-many and many-to-many mappings to some other entities.
Example:
Document:
id,
title,
body,
authors,
viewers,
...
Using REST, I want to update some particular document, controller receives serialized Document object, calling EntityManager's merge method persists null results to the database if controller received for instance only body , then I want the body to be updated only, but merge deletes records for title, authors and viewers and etc.
I understand that it is a standard behavior of EntityManager, but I am asking what is the most preferred technique to do updates on entities without receiving whole entity from front-end or some other endpoint. Should I load the entity from database using the id I received and set MANUALLY all of the fields and then save to database or should I use another technique.
I don't have any problem with writing manually all of the setters to copy the changes, but entities are really big in size with lots of relations. Asking for best practice in this case.
I know about DTOs but I want alternate approach when using entities for controllers and service methods.
For entity partial update, you will need to use either criteria api or jpql ... if you are using older versions with no criteria update or old query parser where jpql update is not allowed you will have to read from database first, update then insert again .... you can also make use of updatable=false for columns that should be only set on creation (like CREATION_DATE) and there is also a nice feature in hibernate called #DynamicUpdate which I haven't tried but looks brilliant ... It only updates the modified field (check Vlad's post here) ... concerning the DTO DP , I you might always need to use if you want to hide / modify some data from the client regardless to the way you store the data ... and it's always a good way to separate concerns (but comes with the mapping headache between domain & DTO objects which is much released thanks to spring converters)
There are two options one is update query, which works fine but you may feel
you are loosing some hibernate features and simplicity of the code. Else you can do it in Hibernate way like below
AuditorBean auditorBean = (AuditorBean) session.get(AuditorBean.class, AuditorBean.getId());
auditorBean.setFirstName("aa");
auditorBean.setLatName("bb");
auditorBean.setTrainLevel("ISO");
auditorBean.setAccessLevel(4);
Here you should not call any method like saveOrUpdate() or merge().
object is attached with transaction, so object is flushed and committed at the end of the transaction automatically .

How many ways Hibernate provide to access database?

How many ways Hibernate provide to access database?
For example, I want to CRUD an object to database, I found out:
Using session from SessionFactory:
session.save(object);
...
Using Hibernate Query Language.
Using Hibernate Criteria Queries.
Using Native SQL.
But I don't know what I should use. Please list your practice to access database in PRIORITY DECREASING ORDER and the reason why you do that.
Thank you.
If you have an ID and wants the associated entity, the use Session.get(). It's efficient, and makes use of the first-level cache to avoid reexecuting the query again and again.
If you need to get entities via other criteria (like all the users with a given first name, for example), then use JPQL queries. They are simple to write, very readable, and have less limitations than criteria queries.
If you need to take various optional criteria (like for a complex search form), the criteria API is the tool for the job. But it can't do everything a JPQL query does. There are other APIs available, and you can relatively easily write an API that generates dynamic JPQL queries if needed.
If you have a really complex query that can't be expressed using JPQL, then use SQL.
To write things to the database, queries should generally not be used, except in very specific circumstances where many entities must be modified the same way. Instead, get the entities to modify, and modify them. Hibernate will save their new state automatically.

JPA and unique fields

I have two persistence objects in my app: Things and tags attached to things. The app can generate collections of things with tags attached. Tag objects have a unique name (it doesn't make sense to tag something twice with the same tag).
When inserting a Thing (with tag objects attached) some of these tag objects with the same name maybe already exist in the db. Now here is the part I don't recall about JPA, is there a way to tell JPA that it should not try to add the corresponding objects to the db if it violates the unique constraint? Or is there a way to do this efficiently w/o having to first fetch all objects, then merge the collection in memory and then write everything back?
I'm also wondering if it's possible to persist a whole collection at once or do I have to call persist for every object when using JPA?
I don't know of any way of doing this 'cleanly', neither with JPA nor with Hibernate or any other provider. You can achieve what you want with a custom SQL query though (similar to this question):
#Entity
#Table(name="tag")
#SQLInsert( sql="INSERT INTO tag(name, count) VALUES (?, ?)
ON DUPLICATE KEY UPDATE set count = count + 1")
public class Tag {}
Now you are unfortunately bound to both Hibernate and MySQL. You can vary the sql syntax for other DB:s, and/or use stored procedures, try an update first and insert on failure etc. They all have their drawbacks, so it would be handy if JPA would support this, but alas.
Regarding you second question, JPA support persisting whole object graphs, including collections.

Categories