I have a database with 3 tables: Slideshows, MediaItemsInSlideshows and Mediaitems. I am using this database with a jsp site using hibernate.
I would like to be able to delete a slideshow without deleting the mediaitems. The rows in the MediaItemsInSlideshows should be deleted though.
Currently I use the following code to remove the slideshow. When I use this all mediaitems that were used in the slideshow are gone.
Session session = HibernateUtil.getSessionFactory().openSession();
Slideshow s = this.getSlideshowById(id, session);
session.beginTransaction();
session.delete(s);
session.getTransaction().commit();
This is a visual representation of the database:
Deleting A will set the reference to it in B to null which is forbidden by the schema. An alternative to changing the order of deletions would be to add a reverse one-to-many collection in B, with cascaded deletes. Only the deletion of A would than be needed.
(source: Deleting of related objects in hibernate)
Related
My goal is
Delete entity in current table
Clone the deleted entity to another table to store for future reference
Thanks
My suggestion is to not delete first, but rather copy the entity into the table you wish, make sure it is successfull by checking the result code, then delete the entity from the table.
INSERT INTO copy_table
SELECT * FROM original_table
WHERE condition;
DELETE FROM original_table
WHERE condition;
In JPA
https://docs.spring.io/spring-data/jpa/docs/1.5.0.RELEASE/reference/html/jpa.repositories.html
Entity x = jpaRepository.findById(id);
cloneTableJpaRepo.save(x);
jpaRepository.delete(x);
I have to improve the performance of a very slow code and I am pretty new to Hibernate. I have studied carefully the code and concluded that the issue is that it has a large set of entities to load and update/insert. To translate the algorithm to a more digestible example, let's say we have an algorithm like this:
for each competitionToSave in competitionsToSave
competition <- load a Competition by competitionToSave from database
winner <- load Person by competitionToSave.personID
do some preprocessing
if (newCompetition) then
insert competition
else
update competition
end if
end for
This algorithm is of course problematic when there are lots of competitions in competitionToSave. So, my plan is to select all competitions and winners involved with two database requests the most, preprocess data, which will quicken the read, but more importantly, to make sure I will save via insert/update batches of 100 competitions instead of saving them separately. Since I am pretty new to Hibernate, I consulted the documentation and found the following example:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
However, I am not sure I understand it correctly. About the method .save() I read:
Persist the given transient instance, first assigning a generated
identifier. (Or using the current value of the identifier property if
the assigned generator is used.) This operation cascades to associated
instances if the association is mapped with cascade="save-update".
But it is unclear to me whether a request to the database is send upon every save. Am I accurate if I assume that in the example taken from the documentation session.save(customer) saves the modification of the object in the Session without sending a request to the database and then on every 20th item the session.flush() sends the request to the database and session.clear() removes the cache of the Session?
You are correct in your assumptions, though the inserts will be triggered one-by-one:
insert into Customer(id , name) values (1, 'na1');
insert into Customer(id , name) values (2, 'na2');
insert into Customer(id , name) values (3, 'na3');
You can try and take advantage of the bulk insert feature to increase the performance even more.
There is hibernate property which you can define as one of the properties of hibernate's SessionFactory:
<property name="jdbc.batch_size">20</property>
With this batch setting you should have output like this after each flush:
insert into Customer(id , name) values (1, 'na1') , (2, 'na2') ,(3, 'na3')..
One insert instead of a twenty.
I have a hibernate code which insert a new role to the table as follows:
Staff staff = new Staff(staffDTO);
Session session = sessionManager.getSession();
session.beginTransaction();
session.save(staff);
session.getTransaction().commit();
Staff is defined as entity.
My question is that how can I get the newly generated row id by the database?
Many thanks.
Hibernate is smart enough :).
After you save the Object in database If you see ,the object have the generated id. Check it.
After save done, just inspect the object and see.
I am very new to Hibernate. I have MySQL database and mapped pojos. What should I do next? I know little bit LINQ to SQL from .NET, and it generates me List of mapped objects.
So basically, what are my next steps after creating POJOS if I want to have List of them and do CRUD operations upon them and data will be also saved in DB not only in java objects ?
kthx
please see the hibernate document - Chapter 10. Working with objects
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html#objectstate-querying-executing
You can createQuery() or createCriteria() to get a list of your pojos. for example:
List cats = session.createQuery("from Cat").list();
or
List cats = session.createCriteria(Cat.class).list();
To answer your question about the rest of CRUD, once you've got your list of objects, as described by qrtt1, then you can manipulate the objects in the session:
Session session = // obtain session
Transaction tx = session.beginTransaction();
List cats = session.createQuery("from Cat").list();
Cat firstCat = (Cat)cats.get(0);
firstCat.setName("Cooking Fat");
firstCat.setOwner("Richard O'Sullivan");
// etc for other cats in the collection
tx.commit();
session.close();
Any objects that you obtained via the query are "dirty checked" at the tx.commit(); this means that in this case an update statement will be issued for the first cat retrieved from the query.
I want update some of my table in database and want all of these work do in 1 transaction,
first of all I delete some entry in branchbuildin(Table) and Insert new one after this action
The problem occurred when I insert and entry with same buildingname and branch_fk (be cause I have this constraint on this table ( uniqueConstraints={#UniqueConstraint(columnNames={"buildingname","branch_fk"})})) but when I don't use hibernate session and use normal JDBC transaction I don't have these problem.
List<Integer> allBranchBuilding = branchBuildingDao.getAllBranchBuildingID(pkId, sess);
for (Integer integer : allBranchBuilding) {
branchBuildingDao.delete(integer, sess); // delete kardane tamame BranchBuilding ha va tel haie aanha
}
Address myAdr = new Address();
setAddress(myAdr, centralFlag, city, latit, longit, mainstreet, remainAdr, state);
BranchBuildingEntity bbe = new BranchBuildingEntity();
setBranchBuildingEntity(bbe, be, myAdr, city, centralFlag, latit, longit, mainstreet, buildingName, remainAdr, state, des);
branchBuildingDao.save(bbe, sess);//Exception Occurred
I get my session at the first of Method:
Session sess = null;
sess = HibernateUtil.getSession();
Transaction tx = sess.beginTransaction();
You're right, everything occurs in the same transaction, and the same Hibernate Session.
The Session keeps track of every entity it manages. Even though you asked to delete it in the database, the corresponding object is still memorised in the Session until the Session is terminated.
In general, it is possible that
Hibernate reorders your operations
when sending them to the database, for
efficiency reasons.
What you could do is flush (ie. send to the database) your transaction because the save (if needed, you could also clear - ie empty the entities memorized by the Session - it after flushing):
sess.flush();
// sess.clear(); // if needed or convenient for you
branchBuildingDao.save(bbe, sess);
Note also that while your entities are memorized by the session, modifying them will trigger an automatic update when closing the session.
In our project, we have a method that deletes efficiently a collection (and another for an array, declared using the convenient ... parameter syntax) of entities (it works for all entities, it doesn't have to be done for each entity), removing them out of the session at the same time, and taking care of the flushing before :
Loop on all entities, delete it (using sess.delete(e)) and add it to a 'deleteds' list.
Every 50 entities (corresponding to the batch size we configured for efficiency reasons) (and at the end) :
flush the Session to force Hibernate to send immediately the changes to the database,
loop on 'deleteds' list, clear each entity from the Session (using sess.evict(e)).
empty the 'deleteds'list.
Don't worry, flush only sends the SQL to the database. It is still subject to commit or rollback.