Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Загрузка объекта из базы в Hibernate


Автор: Nofate 8.9.2009, 22:56
Возникла странная проблема:

Есть небольшой класс:

Код

public class DocumentFolder {
    private int id;
    private String name;
    private DocumentFolder parentFolder;
    private Set<DocumentFolder> subfolders;
    
    /* сеттеры геттеры */
}

и его мапинг
Код

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="ru.arhtorg.docstore.server.domain">
    <class name="DocumentFolder" table="docstore.documentfolders">
        <id name="id" column="id">
            <generator class="sequence">
                <param name="sequence">docstore.documentfolders_id_seq</param>
            </generator>
        </id>    
        <property name="name"/>
        <many-to-one name="parentFolder" class="DocumentFolder">
            <column name="parentfolder"/>
        </many-to-one>
        <set name="subfolders" table="docstore.documentfolders" cascade="all" lazy="false">
            <key column="parentfolder"/>
            <one-to-many class="DocumentFolder"/>    
        </set>        
    </class>
</hibernate-mapping>


в dao-классе осуществляется поиск экземпляра этого класса:
Код

    public Document getDocumentById(int id) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Document result = (Document) session.load(Document.class, id);
        session.getTransaction().commit();
        return result;
    }


Метод отрабатывает без исключений, но в итоге в полях result'а всегда содержит ноли и нуллы. Хотя внутри этой javassist'овской прокси в поле target лежит найденный DocumentFolder и initialized == true.

У кого-нибудь есть идеи, почему так?

Зы. Поиском пользовался )



Автор: garbuz 9.9.2009, 01:33
Попробуйте использовать
Код

Document result = (Document) session.get(Document.class, id);

Автор: MisterCleric 9.9.2009, 09:08
garbuz говорит верно. Вот код EntityManager:
Код

public abstract class EJB3DAO<T, ID extends Serializable> implements DAO<T, ID> {
    protected Class<T> entityBeanType;
    @PersistenceContext
    protected EntityManager em;

    public EJB3DAO() {
        this.entityBeanType = (Class<T>)
                ((ParameterizedType) getClass().getGenericSuperclass())
                        .getActualTypeArguments()[0];
    }

    public T findById(ID id) {
        return em.find(entityBeanType, id);
    }
}
..........................................................................
public abstract class AbstractEntityManagerImpl implements HibernateEntityManagerImplementor, Serializable {
public <A> A find(Class<A> entityClass, Object primaryKey) {
        try {
            return (A) getSession().get( entityClass, (Serializable) primaryKey );
        }
..................................................
}
}

Автор: Nofate 9.9.2009, 11:52
Большое спасибо, помогло.
Непонятна только суть проблемы. Load ведь должен делать то же что и get, но предварительно порывшись в кэше, чтобы базу лишний раз не напрягать. Или я что-то не так понимаю? )

Автор: MisterCleric 9.9.2009, 11:57
Цитата

Load ведь должен делать то же что и get

Читаем JavaDoc org.hibernate.Session
Код

/**
     * Return the persistent instance of the given entity class with the given identifier,
     * or null if there is no such persistent instance. (If the instance is already associated
     * with the session, return that instance. This method never returns an uninitialized instance.)
     * Obtain the specified lock mode if the instance exists.
     *
     * @param clazz a persistent class
     * @param id an identifier
     * @return a persistent instance or null
     * @throws HibernateException
     */
    public Object get(Class clazz, Serializable id) throws HibernateException;


и
Код

/**
     * Return the persistent instance of the given entity class with the given identifier,
     * assuming that the instance exists. This method might return a proxied instance that
     * is initialized on-demand, when a non-identifier method is accessed.
     * <br><br>
     * You should not use this method to determine if an instance exists (use <tt>get()</tt>
     * instead). Use this only to retrieve an instance that you assume exists, where non-existence
     * would be an actual error.
     *
     * @param theClass a persistent class
     * @param id a valid identifier of an existing persistent instance of the class
     * @return the persistent instance or proxy
     * @throws HibernateException
     */
    public Object load(Class theClass, Serializable id) throws HibernateException;


Так вот. Разница в том, что load может вернуть прокси, который проинициализуруется по требованию, а не сразу.

Автор: Nofate 9.9.2009, 12:21
Теперь все ясно. Спасибо, что помогли разобраться.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)