How can I update a row based on id in hibernate - java

I am new in hibernate. I am using SesssionFactory to get the session of the transaction and one way which I found after searching is used for setting few fields using set parameter i.e
Query query = getCurrentSession().createSQLQuery(
"UPDATE table_name set field1=:f1 where ID=:id");
query.setParameter("f1", f1);
query.setParameter("id", id);
but I want to update the whole row. I have already set the values in the entity class but is there a way to pass the values of the whole entity class to the database based on the id the id is the primary key for the table which I want to update.

you already have all data present in the hibernate entity object? Then just call the session directly:
getCurrentSession().save(myEntity);
to create a new object, or
getCurrentSession().update(myEntity);
to update an existing row.
If not sure, you can use:
getCurrentSession().saveOrUpdate(myEntity);

Take a look at Session#update (or saveOrUpdate). This will allow you to persist a complete, mapped, object to the database.

To be as OO as you can, you can get entity by session.get(entityClass, id);
And then after modifying object by setters/getters, you can save it back to the DB using update method :session.update(entity);

Related

DAO design to update an entity in DB

Lets say a client updates an entity ( Ex: student entity ).
So we get the student Id and other modified fields (not all fields) from the client.
I read that we should pass the particular entity object to DAO in order to update.
But then , how will I get to form that entity object.Because I don't have all fields data to create a proper entity object.
Should I make two DB calls ?
The first call is to construct a proper entity object and then make the update by passing this updated entity object to the DAO.
The only way to avoid two DB calls is to use an update statement to update only th fields you have. E.g.
UPDATE Student SET someField1 = :field1, someField2 = :field2 WHERE ID = :id
Remember that update queries bypass optimistic locking checks.
If you use optimistic locking you should append the version to the where clause and also increment it.
UPDATE Student SET someField1 = :field1, version = version + 1 WHERE id = :id AND version = :version
After an executeUpdate you should check the affected rows:
1 : everything is ok
0 : the entity could either not be found by it's id. Maybe it was deleted in the meanwhile or the version did not match. In both cases you should raise an OptimisticLockException.
>1 : you should raise an exception to rollback the transaction.

Get just added Object with EntityManagerFactory

I'm developing a java app with MySql database, JPA objects and EntityManagerFactory with EclipseLink to manage the database. Everything works Ok but I have an issue.
One of my JPA objects is like this
public class JPAObject1{
#Id
#GeneratedValue
private int id;
#OneToMany(//things here)
List<JPAObject2> list1;
...
}
So the id field will be autogenerated by the EntityManagerFactory when I store it in the database. Asumming em type EntityManager and object type JPAObject1:
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
//house work closing things
The JPAObject1 is added correctly, I can see all fields in my database. As field id is the key to do the find operation, my question is:
Is there a way to get the last added object on the EntityManager on just the moment it is added?
Because I have others objects that use the JPAObject1 id field as a foreign key and I need that field when just the object is added to the database to link the others, but the only way I know to get it is getting all the JPAObjects and getting the last one in the Collection. So, with a few Objects it won't be a problem but if one process insert on database and another do the same before process 1 does the findAll to get the last added, there will be a coherence error....
I think I've explained it well.
Thanks a lot!
you can use this code
Obejct en = new Obejct ();
en.setxxx("My name");
em.persist(en);
em.flush();
System.out.println(en.getId());
the id genrated after flush
Note that the datas saved to database is a set, not list. So they don't have the order or anything like that, and you can't get the last one you've added. If you want to, pls add a column like date, time..., and the query will be like:
" SELECT * FROM Table ORDER BY dateColumn DESC LIMIT 1"

Hibernate creates new row on save and not updates

I am using MySQL + spring + hibernate.
When I execute the following code it creates a new row:
sessionFactory.getCurrentSession()
.save(configTable);
However this code below updates
sessionFactory.getCurrentSession()
.update(configTable);
I am not sure why the above code creates a new row in tables it should update in both cases to my understanding,
Any idea what could I be missing? Or what info will you need to help me track the problem...
You need to use saveOrUpdate() session method as:
sessionFactory.getCurrentSession().saveOrUpdate(configTable);
When update pass Entity primary key for update.
Make sure that your Entity have this annotation for save and update.
#org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)

OpenJPA inserting into one table data from another table

I am new to OpenJPA
I am trying to insert data into a table some of which comes from another table. Below is the scenario.
Table1: id, app_name, app_version, app_active
Table2: id, app_name, app_version, dev_name, dev_Lastname, dev_shortname,
Pojo1 maps fields to column of table1
Pojo2 maps fields to column of table2
Query:
insert into table2 ("dev_name","dev_lastname","dev_shortname") select t1.app_name, t1.app_version from Table1 t1 where t1.app_name = ?
i dont know how to run this query using Openjpa and how to map these fields to each other in two pojos.
if I use the Query object then what about the pojos?? will they come in use?? I mean will i need to do transaction.save??
Any help with a sample code appreciated.
Your query manipulates data directly in the database while JPA handles the object relationships.
Im not sure what problem you are trying to solve but can you read the Pojo1 convert it to a Pojo2 object that you just save?
Edit:
In you java application first retrieve your Pojo1 from the entity manager with some query.
Then Construct corresponding Pojo2 objects with the fields you want from Pojo1. Then just to entityManager.persist with your new Pojo2 objects.
This is quite complex to perform what you showed could be made in a one line sql statement.

How do you update a foreign key value directly via Hibernate?

I have a couple of objects that are mapped to tables in a database using Hibernate, BatchTransaction and Transaction. BatchTransaction's table (batch_transactions) has a foreign key reference to transactions, named transaction_id.
In the past I have used a batch runner that used internal calls to run the batch transactions and complete the reference from BatchTransaction to Transaction once the transaction is complete. After a Transaction has been inserted, I just call batchTransaction.setTransaction(txn), so I have a #ManyToOne mapping from BatchTransaction to Transaction.
I am changing the batch runner so that it executes its transactions through a Web service. The ID of the newly inserted Transaction will be returned by the service and I'll want to update transaction_id in BatchTransaction directly (rather than using the setter for the Transaction field on BatchTransaction, which would require me to load the newly inserted item unnecessarily).
It seems like the most logical way to do it is to use SQL rather than Hibernate, but I was wondering if there's a more elegant approach. Any ideas?
Here's the basic mapping.
BatchQuery.java
#Entity
#Table(name = "batch_queries")
public class BatchQuery
{
#ManyToOne
#JoinColumn(name = "query_id")
public Query getQuery()
{
return mQuery;
}
}
Query.java
#Entity
#Table(name = "queries")
public class Query
{
}
The idea is to update the query_id column in batch_queries without setting the "query" property on a BatchQuery object.
Using a direct SQL update, or an HQL update, is certainly feasible.
Not seeing the full problem, it looks to me like you might be making a modification to your domain that's worth documenting in your domain. You may be moving to having a BatchTransaction that has as a member just the TransactionId and not the full transaction.
If in other activities, the BatchTransaction will still be needing to hydrate that Transaction, I'd consider adding a separate mapping for the TransactionId, and having that be the managing mapping (make the Transaction association update and insert false).
If BatchTransaction will no longer be concerned with the full Transaction, just remove that association after adding a the TransactionId field.
As you have writeen, we can use SQL to achieve solution for above problem. But i will suggest not to update the primary keys via SQL.
Now, as you are changing the key, which means you are creating alltogether a new object, for this, you can first delete the existing object, with the previous key, and then try to insert a new object with the updated key(in your case transaction_id)

Categories

Resources