3

How to get the value which being saved to database after

entityManager.persist

I am able to get the primary key value from database after calling persist not any other values. E.g.

public void create(Project project) {
    entityManager.persist(project);     
    System.out.println("Id    -- " + project.getProjectId());
    System.out.println("no -- " + project.getProjectNo());
}

From the above code I am able to get the newly inserted value from project.getProjectId, however not able to get project.getProjectNo

The reason why I am able to get projectId is because it is primary key?

How can I get the value of getProjectNo after persist?

Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
Jacob
  • 14,463
  • 65
  • 207
  • 320
  • Is ProjectNo a generated value? Are you sure it is set prior to the call to persist? Does the value appear in the database? If it is not generated and your setting the value, the orm shouldn't null out the field. – Kevin Bowersox Jul 25 '13 at 11:38
  • @KevinBowersox `projectNo` is a database generated value using database trigger. – Jacob Jul 25 '13 at 11:41
  • You will need to setup a sequence generator. It might work with identity, as this assumes the database will set the id in the insert just as your trigger does. – Chris Jul 25 '13 at 12:10
  • @Chris You mean to say that as projectNo is not unique key and projectId being the id and being triggered is getting the value back from database? – Jacob Jul 25 '13 at 12:14
  • No, I am saying that JPA has no way of getting the value set by the trigger unless you tell it that the value is set by the database on insert. The way to do that is to specify that sequencing is used, and GenerationType.IDENTITY specifically. This will tell JPA that the database is setting the value, so it can go about looking it up using your database's specific ways. See http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Identity_sequencing – Chris Jul 25 '13 at 12:59
  • I read this incorrectly - sequencing is only available on IDs. Kevin's answer is on the right track, as you already have the PK that was set. You need to call flush() and then em.refresh(project) so the non-pk fields set by the trigger are read in. Alternatively, some providers allow setting returning policies that can get the values for non-pk fields set using triggers. Hibernate may have an equivalent to EclipseLink's http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_returninsert.htm#CIHHEGJE – Chris Jul 25 '13 at 13:02

1 Answers1

5

Try refreshing the entity with the database to get the inserted trigger value.

public void create(Project project) {
        entityManager.persist(project);
        entityManager.getTransaction().commit();
        project = entityManager.find(Project.class, project.getProjectId());
        entityManager.refresh(project);
        System.out.println("Id    -- " + project.getProjectId());
            System.out.println("no -- " + project.getProjectNo());
    }

Documentation

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Refresh won't work unless it has the id to use in the refresh query. – Chris Jul 25 '13 at 12:06
  • Kevin adding `entityManager.refresh` resulted in the following exception `org.hibernate.HibernateException: this instance does not yet exist as a row in the database` – Jacob Jul 25 '13 at 12:06
  • what if you flush the entityManager? `entityManager.flush();` – Kevin Bowersox Jul 25 '13 at 12:08
  • `entityManager.flush();` is not causing any errors, but `projectNo` is still null; – Jacob Jul 25 '13 at 12:13
  • and the value is present in the database? – Kevin Bowersox Jul 25 '13 at 12:14
  • Kevin Yes `projectNo` does exist in table, it is getting generated using a trigger. Trigger code for generating `projectId` and `projectNo` is one and same. – Jacob Jul 25 '13 at 12:17
  • @Polppan sorry we just hadn't established that yet. Need to check all the points of failure. – Kevin Bowersox Jul 25 '13 at 12:21
  • @Polppan see updates and this post: http://stackoverflow.com/questions/13389279/how-to-sync-entity-bean-with-database-after-trigger-update – Kevin Bowersox Jul 25 '13 at 12:23
  • @KevinBowersox I have modified my code with your updated suggestions, however I am getting `org.hibernate.HibernateException: this instance does not yet exist as a row in the database` exception. – Jacob Jul 25 '13 at 12:35
  • It seems like the record is not being committed, call `commit()` via the em. This may make the call to find the entity unnecessary. – Kevin Bowersox Jul 25 '13 at 12:40
  • @Polppan no but it has `getTransaction()` which has `commit()` see the update I provided. – Kevin Bowersox Jul 25 '13 at 12:43
  • Kevin I have the following exception `java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManag erCreator.java:198) at com.sun.proxy.$Proxy29.getTransaction(Unknown Source)` – Jacob Jul 25 '13 at 12:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34161/discussion-between-polppan-and-kevin-bowersox) – Jacob Jul 25 '13 at 13:44