Существует ли способ изменить тип выборки JPA на методе?

Возврат отката сделает свое дело

Например,

If abcdef is your commit and ghijkl is the commit you have when you reverted the commit abcdef,

Затем введите

git revert ghijkl

Это вернет возврат

18
задан moffeltje 9 June 2019 в 20:37
поделиться

2 ответа

Я предполагаю, что ваши ассоциации сущностей (@OneToOne, @OneToMany, @ManyToOne) являются ленивыми (FetchType.Lazy)

Тогда я могу думать о двух способах:

A. напишите два запроса jpa: один, который извлекает ассоциацию ленивого (это способ по умолчанию для спящего режима), и второй запрос, который явно заставляет нетерпеливую загрузку ассоциации (см. ключевое слово "fetch" в запросе).

        Query q = HibernateUtil.getSessionFactory().getCurrentSession()
                .createQuery("select c from Category as c" +
                        " left join fetch c.categorizedItems as ci" +
                        " join fetch ci.item as i");


B. используйте Hibernate.initialize (entity) для принудительной загрузки ленивых отношений объекта после того, как вы его получили (например, через Finder ...)

ErrorCode lazyCode = findErrorCodeById(1);
// eager load associations
Hibernate.initialize(lazyCode);
16
ответ дан 30 November 2019 в 08:21
поделиться

In JPA the Fetch mode is specified on each persistence attribute, either through an annotation or in an xml mapping file.

So a JPA vendor agnostic way to accomplish your goal is to have separate mapping file for each DAO layer. Unfortunately this will require a separate PersistenceUnit for each mapping file, but you can at least share the same entity classes and the same JPQL query.

Code skeletons follow.

persistence.xml :

<persistence>
    <persistence-unit name="dao-eager">
        <mapping-file>orm-eager.xml</mapping-file>
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>

orm-eager.xml :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="EAGER"/>
        </attributes>
    </entity> 
</entity-mappings>

orm-lazy.xml :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <basic name="name" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

Then it's just a matter of creating an EntityManagerFactory for the appropriate persistence-unit in your DAO layers.

Actually you don't need two mapping files, you could specify either LAZY or EAGER as an annotation in the Entity and then specify the opposite in an xml mapping file (you'll still want two persistence-units though).

Might be a little more code than the Hibernate solution above, but your application should be portable to other JPA vendors.

As an aside, OpenJPA provides similar functionality to the Hibernate solution above using FetchGroups (a concept borrowed from JDO).

One last caveat, FetchType.LAZY is a hint in JPA, the provider may load the rows eagerly if needed.

Updated per request.

Consider an entity like this :

@Entity 
public class ErrorCode { 
    //  . . . 
    @OneToMany(fetch=FetchType.EAGER)  // default fetch is LAZY for Collections
    private Collection myCollection; 
    // . . .
}

In that case you'd still need two persistence units, but you'll only need orm-lazy.xml. I changed the field name to reflect a more realistic scenario (only collections and blobs use FetchType.LAZY by default). So the resulting orm-lazy.xml might look like this :

<entity-mappings>
    <entity class="ErrorCode">
        <attributes>
            <one-to-many name="myCollection" fetch="LAZY"/>
        </attributes>
    </entity> 
</entity-mappings>

And persistence.xml will look like this :

<persistence>
    <persistence-unit name="dao-eager">
       <!--
          . . .
         -->
    </persistence-unit>

    <persistence-unit name="dao-lazy">
        <!--
           . . . 
          -->
        <mapping-file>orm-lazy.xml</mapping-file>
    </persistence-unit>
</persistence>
9
ответ дан 30 November 2019 в 08:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: