| Consider the following simplified example: ```java @Table(name = "CONTAINER") class Container { @OneToMany(fetch = FetchType.EAGER) @JoinColumn(name = "CONTAINER_ID", referencedColumnName = "ID") @MapKey(name = "key") @Fetch(FetchMode.SUBSELECT) private Map<Longs, MappedAttribute> mappedAttributes; @Transient private BusinessAttribute businessAttribute; @PostLoad private void postLoad() { this.businessAttribute = new BusinessAttribute(mappedAttributes); } } @Table(name = "ATTRIBUTES") class MappedAttribute { ... } class BusinessAttribute { public BusinessAttribute(List<MappedAttribute> args){} } ``` When I call ``` entityManager.createQuery("Select c from " + Container.class.getName() + " c where c.id in (1, 2, 3, 4)").getResultList(); ``` Then hibernate executes the following SQL (simplified a little bit, for confidentiality) ```sql – First select the root objects select * from CONTAINER where ID in (1,2,3,4); – Then select all the attribute rows for each root object in individual queries select * from ATTRIBUTES where CONTAINER_ID = 1; select * from ATTRIBUTES where CONTAINER_ID = 2; select * from ATTRIBUTES where CONTAINER_ID = 3; select * from ATTRIBUTES where CONTAINER_ID = 4; ``` This is the kind of 1+N SQL queries that I would expect to see if I had set FetchMode.SELECT, and does not seem consistent with FetchMode.SUBSELECT If I comment out the @PostLoad annotation on Container.postLoad(), then hibernate runs the following SQL queries: ```sql – First select the root objects select * from CONTAINER where ID in (1,2,3,4); – The select all the attributes for all root objects at once select * from ATTRIBUTES where CONTAINER_ID in ( select ID from CONTAINER where ID in (1,2,3,4) ); ``` Which is what I had expected it to do. @PostConstruct annotations should not disable FetchMode.SUBSELECT when all of the persistent attributes are eagerly loaded, or when the callback (or entity listener) does not alter any of the persistent properties of the parent entity. In my case, all of my fields are either basic, transient or associations annotated with FetchType.EAGER, so there is no chance that whatever happens in the postConstruct() method would affect any association. Alternately, if it is impossible or impractical to detect that the whole entity and all its associations are eagerly loaded, hibernate should provide a mechanism so that a developper can specify the behavior of the listener to hibernate (maybe via an @ListenerProperties(TRANSIENT_ONLY) annotation, or maybe with another @Parameters annotation. |