2

TL;DR: Why aren't the results of my call to query.getSingleResult() or query.getResultList() being managed by the persistence context? I'm getting the query objects from the entity manager so they absolutely should be, no? This question indicates it should: When I use A JPA Query's getResultList(), are the results detached or managed?

So I am using OpenJPA in Spring and have some entities listened on by an entity listener of course. The entity listener listens for two lifecycle callbacks: pre-persist and post-load. Pre-persist goes through just fine, but post-load never happens I imagine because I am using native queries in my repository (via the @Query annotation on my JpaRepository).

Example:

public interface MyEntityRepo extends JpaRepository<MyEntity, String> {
    @Query(value = "...", nativeQuery = true)
    private MyEntity someNativeQuery(String name, String id);
}

So I thought perhaps I should "implement" this repository to call the entity manager directly via em.createNamedQuery("...", MyEntity.class) and annotate my entity with the @NamedQuery so that the object returned is being managed by the persistence context. This is of course a hypothesis of mine, so please feel free to correct me if I'm wrong since the rest of the question then becomes kind of pointless.

Issue now is I was using native queries because I want to call some DB specific functions that aren't SQL standard, so the named queries didn't work out whatever I did. (i.e. using func('db_fun', parameters) or function('db_fun', parameters) would throw parsing exceptions when getting data) so I decide to use the @NamedNativeQuery annotation on my entity with the old native query.

Once again this failed to trigger the post-load lifecycle callback even though it gets the object from the DB. What do?

Entity

@NamedNativeQueries({@NamedNativeQuery(name = "...", query = "...", resultClass = MyEntity.class)})
@EntityListeners(MyEntityListener.class)
public class MyEntity implements Serializable {
    ...
}

Entity listener

public class MyEntityListener {
    @PostLoad
    public postLoadFunction(MyEntity myEntity) {
        ... //never reached :(
    }
}

Repository Implementation

public class MyEntityRepositoryImpl {
    @PersistenceContext
    private EntityManager em;

    MyEntity myProblematicQuery(Object parameters, ...) {
        TypedQuery<MyEntity> query = em.createNamedQuery("myNamedNativeQuery", MyEntity.class).setParameter(...);
        return query.getSingleResult();
    }
}
Community
  • 1
  • 1
rawa
  • 315
  • 3
  • 8
  • 20

0 Answers0