Spring Data JPA. Update entity wihtout using id - java

I have Flat entity. I need to update a lot of rows in relevant table, but I don't know ids of updated rows. I know that there are some ways of doing it:
Select all flats by unique parameter (not #Id), update persisted entity and then save it.
I don't want use it, because I have to get from database a lot of entities, when I really don't need it.
Create update method in JpaRepository with #Modifying and #Query annotations like Update Flat f SET ..fields... WHERE f.unique_field=?1 But in my case Flat entity contains 20+ fields, so my method will have 20+ parameters that is not very beatifull.
Is there another way to update entities without knowing id and select queries?
I hope that there is something that looks like 2nd way but with entity as parameter of update instead of plenty fields.
For example
#Modifying
#Query("Update Flat f where f.unique_field=?1)
Flat updateFlatByUniqueField(Flat flat, Long uniqueField)

Related

How to represent table with nulls in Spring Data JPA?

What should I do to represent this table in Spring Data Java Persistence Application Programming Interface (JPA)?
The table is specific because it has no primary key and every column in the table can have nulls, and it is read only.
In entity class I can not simply annotate a single column with #id because there is no column with unique values.
I can, of course, create composite virtual primary key in entity class by annotating every column with #id, and that works, but only if there are no nulls in the row. So if I select row(s) with all columns not null then this works. But if one or more columns contains null, Spring is not able to extract that row from table, and instead returns simply null for entire row rather than returning an entity object with only the appropriate field null.
Please do not say "just add id column to the table" because table is read only for us. My company was negotiating for more then a month just to get the read rights to the table! I can not simply add id field in the table.
What else can I do in this case? Other than manually executing a query and extracting the result. Can I somehow fake the id field to make Spring happy? id field is not important for our application, we will never filter the table by id, so it can be whatever makes Spring happy as far as I am concerned.
I don't think there is a way to do that.
Just get a NamedParameterJdbcTemplate injected and query away.
A central premise of JPA is that you can load data from a bunch of tables, edit the resulting object structure and JPA will take note and mirror the changes to the data in the database.
If you don't have anything to use as an id you wouldn't know which row to update. So this whole approach kinda fails to work.
You can use #EmeddedId with an ID you create. Set the ID field either #Transient or static so it won't affect persistence.
In the below example I use the UUID static method .randomUUID() to generate the ID.
So put this into your #Entity and you will get every row regardless of nulls. Inserts will work just fine too (depending on how you disambiguate your rows).
#EmbeddedId
static UUID uuid = UUID.randomUUID();

Java Persist without Entity

I am working on an JavaEE application, and there are almost 1000+ tables in the database, now I have to query the records by the parametes from the client.
Generally I will create one Entity for each table, and create the Dao,Service to do the query.
However I meet two problems:
1 Number of the tables
As I said, 1000+ table with almost 40+ columns for each, it would a nightmare to create the entity one by one.
2 Scheme update
Even I can create the Entity by program, the schema of the data may change sometime which is out of my control.
And in my application, only read operations are related to these kinds of data,no update,delete,create required.
So I wonder if the following solution is possible:
1 Use Map instead of POJOs
Do not create POJOs at all, use the native Map to wrap the columns and values.
2 Row mapping
When querying using Hibernate or Spring JdbcTemplate or something else, use a mapper to map each row to an entry in the map.
If yes, I would use the ResultMetaData to detect the column name,type,value:
ResultMetaData rmd=rs.getMetaData();
for(int i=0;i<rmd.getColumnCount();i++){
Type t=rmd.getType(i)
if(t==....){
...
}else if(t=...){
...
}
}
Looks like part of JPA's job, any library can used here?
If not, any other alternatives?

How to get all data in Audited table with hibernate envers?

I have a project where i have all my entities. And I have another project where I try to get all the data of each Audited table of each given Entity.
With Hibernate envers i know how to retrieve an object in a previous version.
AuditReaderFactory.get(Session sess) and Object AuditReader.find(Class<T> cls, Object primaryKey, Number revision)
But I don't know how to get All records data in an audited X with the rev et typerev field too.
Any idea?
Because i want to get a lot of data from an audited table (in some table i find the millions of revisions so to get that they take a lot of time whitch cause a timout for the server , specialy when i use hibernate envers , that why i change to native query and i found a lot of possibilities and fonctionalities in.

adding select count to vaadin datasource

Hi I have a case where I need to do this select statement
SELECT c.*, count(r.competitorid) as num_comp, num_event.num_events
from competition c left join regcomp r on c.competitionid = r.competitionid
left join
(
select competition.competitionid, count(e.competitionid) as num_events
from competition left join `event` e on competition.competitionid = e.competitionid
group by competition.competitionid
) as num_event on c.competitionid = num_event.competitionid
)
AS winners ON winners.competitionid = c.competitionid;
My problem is that I do not know what pattern follow, or if there's a set of methods that I need to call to create the datasource for this table. I can create an IndexedContainer and add container properties, then add that to the Vaadin table, which is what I'm doing - but the problem is when I try to persist data, I am not able to use JPA later if I don't use it at the start.
JPA lets you access referenced tables via foreign keys very conveniently by doing setVisibleColumns("parent.child") and so it is possible in theory to show any information about a single row by picking the correct entry-entity so to speak.
But what do I do if I want to create a table that shows counts in one of the columns, obviously the count is not part of the entity - but if it isn't part of the entity how can I use the benefits of JPA on tables that include data generated by stuff like avg(), count() etc.
P.S. the query retrieves a table showing all the competitions and how many competitors and events are in that competition.
This depends on what JPA provider you use.
When using Hibernate you can use calculated properties as mentioned in this post.
It then gives such annotations:
#Formula("PRICE*1.155")
private float finalPrice;
or even more complex
#Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)")
private Date firstOrderDate;
Look at the other post for more details on this Hibernate feature.
For EclipseLink/Toplink I know of no solution to the problem
Persistence means you have strong link between your classes and database tables, which are "hard, durable" things.
In your queston you are fetching data from a query, not a table, so talking about persistence in this context is not correct.
What you can do is to add in your Table a custom column where you make your custom things,
or make a database view and create an Entity on it (could autogenerate with JPATools) if you want to have the full power of JPAContainer.
Cheers.

Optimize Hibernate entities saving?

Is there a way to reduce unnecessary/empty fields in SQL inserts and SQL updates?
For example, I have a single hibernate entity class mapped to a table that has 10 columns. The populating of data is actually done in two phases. When the user submit a request, I will insert the request information into the table with the hibernate entity, but populating only 7 fields. After some processing (wait for other users interaction for example), I will populate the remaining 3 fields (with the id given from the previous insert).
If I stick with a single entity class, for the second update, the steps I do is as follows:
1) Load the entity identified by id
2) Save the entity, which generates sql that seems to be sending all the fields over.
Alternatively, I created two entity class, and point to the same table and save them seperately.
Does anyone have a better suggestion?
Kent
Edit:
What I really like to achieve is something to the following effect:
insert t(id,field1,field2) (?,?,?)
update t set field3=? field4=? where id=?
The best I could achieve now with dynamicUpdate=true is
insert t(id,field1,field2) (?,?,?)
select field1,field2,field3,field4 from t where id=?
update t set field3=? field4=? where id=?
Is there a way to eliminate that select statement? The original persisted object is not stored anywhere in memory after the insert.
An additional note. The entity class is annotated with Hibernate validation. I am currently trying out to achieve the above desired effect, so I commented them out. But when I turn them back on, I get validation errors due to #NotNull and #NotEmpty.
If you add the annotation:
#org.hibernate.annotations.Entity(dynamicUpdate = true)
to the top of your entity only the fields that have changed will be sent to the database.

Categories

Resources