Skip to content

Commit 3b597f5

Browse files
committed
Fix unresolved Hibernate proxies
1 parent 57c89df commit 3b597f5

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

app/dao/impl/jpa/JpaElementDao.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import dao.ElementDao;
55
import javabean.JavaBeanHelper;
66
import jpa.manager.JPAManager;
7+
import org.hibernate.Hibernate;
78
import org.omg.sysml.internal.CommitIndex;
89
import org.omg.sysml.internal.impl.CommitIndexImpl;
910
import org.omg.sysml.internal.impl.CommitIndexImpl_;
@@ -33,8 +34,7 @@
3334
@Singleton
3435
public class JpaElementDao extends JpaDao<Element> implements ElementDao {
3536
// TODO Explore alternative to serializing lazy entity attributes that doesn't involve resolving all proxies one level.
36-
static Consumer<Element> PROXY_RESOLVER = element -> JavaBeanHelper.getBeanPropertyValues(element).values().stream().flatMap(o -> o instanceof Collection ? ((Collection<?>) o).stream() : Stream.of(o)).forEach(o -> {
37-
});
37+
static Consumer<Element> PROXY_RESOLVER = element -> JavaBeanHelper.getBeanPropertyValues(element).values().stream().flatMap(o -> o instanceof Collection ? ((Collection<?>) o).stream() : Stream.of(o)).filter(o -> o instanceof Element).map(o -> (Element) o).forEach(Hibernate::unproxy);
3838

3939
@Inject
4040
private MetamodelProvider metamodelProvider;
@@ -92,7 +92,7 @@ public Set<Element> findAllByCommit(Commit commit) {
9292
return jpa.transact(em -> {
9393
// TODO Commit is detached at this point. This ternary mitigates by requerying for the Commit in this transaction. A better solution would be moving transaction handling up to service layer (supported by general wisdom) and optionally migrating to using Play's @Transactional/JPAApi. Pros would include removal of repetitive transaction handling at the DAO layer and ability to interface with multiple DAOs in the same transaction (consistent view). Cons include increased temptation to keep transaction open for longer than needed, e.g. during JSON serialization due to the convenience of @Transactional (deprecated in >= 2.8.x), and the service, a higher level of abstraction, becoming aware of transactions. An alternative would be DAO-to-DAO calls (generally discouraged) and delegating to non-transactional versions of methods.
9494
Commit c = em.contains(commit) ? commit : em.find(metamodelProvider.getImplementationClass(Commit.class), commit.getId());
95-
return getCommitIndex(c, em).getWorkingElementVersions().stream().map(ElementVersion::getData).filter(mof -> mof instanceof Element).map(mof -> (Element) mof).collect(Collectors.toSet());
95+
return getCommitIndex(c, em).getWorkingElementVersions().stream().map(ElementVersion::getData).filter(mof -> mof instanceof Element).map(mof -> (Element) mof).peek(PROXY_RESOLVER).collect(Collectors.toSet());
9696
});
9797
}
9898

@@ -113,7 +113,10 @@ public Optional<Element> findByCommitAndId(Commit commit, UUID id) {
113113
builder.equal(elementIdentityJoin.get(ElementIdentityImpl_.id), id)
114114
);
115115
try {
116-
return Optional.of(em.createQuery(query).getSingleResult()).map(ElementVersion::getData).filter(mof -> mof instanceof Element).map(mof -> (Element) mof);
116+
return Optional.of(em.createQuery(query).getSingleResult()).map(ElementVersion::getData).filter(mof -> mof instanceof Element).map(mof -> (Element) mof).map(element -> {
117+
PROXY_RESOLVER.accept(element);
118+
return element;
119+
});
117120
} catch (NoResultException e) {
118121
return Optional.empty();
119122
}

0 commit comments

Comments
 (0)