1

Trying to use a for loop to save/commit data using hibernate 4.3.11.Final with SQLite Dialect com.enigmabridge:hibernate4-sqlite-dialect

When I run this code and check the Sqlite data, I see that it's only saved 1 item (seems like it only commits once) and that one item is the last (of the 5 items I've generated) that I see in the database.

configureSessionFactory();
Session session = null;
Transaction tx=null;
try {
    session = sessionFactory.openSession();
    SyndEntry entry = null;
    URL feedUrl = new URL(rssUrl);
    SyndFeedInput input = new SyndFeedInput();
    SyndFeed feed = input.build(new XmlReader(feedUrl));
    tx = session.beginTransaction();
    BroadcastItem item = new BroadcastItem();
    for (int i = 0 ; i < 5 ; i++) {
         entry = (SyndEntry) feed.getEntries().get(i);
         item.setMessage(entry.getTitle());
         item.setLinkUrl(entry.getLink());
         session.save(item);
    }
    tx.commit();
} catch (Exception ex) {
  ex.printStackTrace();
  // Rolling back the changes to make the data consistent in case of any failure in between multiple database write operations.
   tx.rollback();
} finally{
  if(session != null) {
      session.close();
  }
}

But when I move tx = session.beginTransaction(); inside the for loop, I get

nested transactions not supported

  1. How can I accomplish what I want (loop 5 times, adding a data item each time into the database)?
  2. Why does commit only run once here?
Tlink
  • 875
  • 2
  • 14
  • 30
  • I get it that it could be confusing, but I've included it because the way I understand it is that JDBC is always present, at low level, Hibernate builds on top of it. And I think of JPA is a specification and Hibernate is an implementation (the way EclipseLink is) we use JPA annotations. Not trying to argue against my tags can confuse people, just wanted to point out the reasons. – Tlink Apr 25 '18 at 14:07
  • You're correct about the question is a Hibernate one. But my BroadcastItem class has `javax.persistence.*` import. this answer here has cleared things for me : https://stackoverflow.com/questions/15040583/relation-between-jpa-and-hibernate-annotation – Tlink Apr 25 '18 at 14:19

1 Answers1

6

When you write

    BroadcastItem item = new BroadcastItem();

    for (int i = 0 ; i < 5 ; i++) {
        entry = (SyndEntry) feed.getEntries().get(i);

        item.setMessage(entry.getTitle());
        item.setLinkUrl(entry.getLink());

        session.save(item);
    }

You save (create) your item the first time, and for the other times of your loop, you save (update) your item.

You just need to put your creation of your BroadcastItem in the loop as follows:

    for (int i = 0 ; i < 5 ; i++) {
        entry = (SyndEntry) feed.getEntries().get(i);
        BroadcastItem item = new BroadcastItem();

        item.setMessage(entry.getTitle());
        item.setLinkUrl(entry.getLink());

        session.save(item);
    }
DamCx
  • 1,047
  • 1
  • 11
  • 25
  • This works, thanks, but is there a way to avoid creating an object each time? is there a way to RECYCLE the same object again and again? – Tlink Apr 25 '18 at 13:59
  • No, you can't, as your object is kinda 'marked as known' by your Hibernate session. One way to see it clearly is if your `item` possess an auto incremented id, which will help you understand better your point. In a more visual way, see it as if you were creating one box with 2 drawers, in which you put your 2 values, and change them each time you loop on it: it remains the same box, with different values. – DamCx Apr 25 '18 at 14:02
  • Yes, that made it very clear, is there another way to do this more efficiently? using streams on any other strategy? I'm asking because I might have to insert 5000 items each time. Thanks again. – Tlink Apr 25 '18 at 14:09
  • Even if you use streams, you will have to make a `new BroadcastItem()` each time, unfortunately – DamCx Apr 25 '18 at 14:12
  • Ok, thanks. When running the code in IntelliJ it seems it does not stop after execution, when I click the STOP button , it displays the following message `Process finished with exit code 130 (interrupted by signal 2: SIGINT)` did I miss anything after `session.close()`? – Tlink Apr 25 '18 at 14:43