2

私はこの例外を受けています:

javax.el.ELException: Error reading 'id' on type com.example.model.Article_$$_javassist_2
...

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149)
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195)
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
com.example.model.Article_$$_javassist_2.getId(Article_$$_javassist_2.java)
...

これが私のコードです:

@Entity
@Table( name = "tbl_articles" )
public class Article implements Comparable<Article>, Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @Column( nullable = false )
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    private Integer id;

    // some other fields

    @ManyToMany( cascade = { CascadeType.ALL } )
    @JoinTable( name = "tbl_articles_categories",
        joinColumns = { @JoinColumn( name = "article_id" ) },
        inverseJoinColumns = { @JoinColumn( name = "category_id" ) })
    @ForeignKey( name = "tbl_articles_categories_fkey_article",
        inverseName = "tbl_articles_categories_fkey_category" )
    private Set<Category> categories = new HashSet<Category>();

    @ManyToMany( cascade = { CascadeType.ALL } )
    @JoinTable( name = "tbl_articles_tags",
        joinColumns = { @JoinColumn( name = "article_id" ) },
        inverseJoinColumns = { @JoinColumn( name = "tag_id" ) })
    @ForeignKey( name = "tbl_articles_tags_fkey_article",
        inverseName = "tbl_articles_tags_fkey_tag" )
    private Set<Tag> tags = new HashSet<Tag>();

    // getters and setters
}

public abstract class BaseService<E, D extends BaseDAO<E>>
{
    protected D dao;

    public BaseService()
    {
    }

    protected D getDao()
    {
        return dao;
    }

    @Autowired
    protected void setDAO( D dao )
    {
        this.dao = dao;
    }

    @Transactional
    public E get( int id )
    {
        return dao.get( id );
    }
}

@Service
public class ArticleService extends BaseService<Article, ArticleDAO>
{
    public ArticleService()
    {
        setDAO( dao );
    }
}

public abstract class BaseDAO<E>
{
    public abstract E get( int id );
}

@Repository
public class ArticleDAO extends BaseDAO<Article>
{
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Article get( int id )
    {
        return ( Article ) sessionFactory.getCurrentSession().load( Article.class, id );
    }
}

私のコントローラーでは、これを使用して特定の記事を取得しています。

@RequestMapping( "/{id}/{title}.html" )
public String article( @PathVariable( "id" ) Integer id, Map<String, Object> map )
{
    map.put( "article", articleService.get( id ) );
    return "article";
}

JSPで次のように使用しています:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="slg" uri="http://github.com/slugify" %>
<article>
    <c:url value="/blog/${article.id}/${slg:slugify(article.title)}.html" var="articleUrl" />
    <h2><a href="${articleUrl}">${article.title}</a></h2>
    <span><fmt:formatDate value="${article.creationDate}" pattern="E, dd MMM yyyy" /></span>
    <p>
        ${article.text}
    </p>
</article>

これも私の休止状態の設定です:

# Properties file with Hibernate Settings.

#-------------------------------------------------------------------------------
# Common Settings

hibernate.generate_statistics=false
#hibernate.hbm2ddl.auto=update
hibernate.show_sql=false

#-------------------------------------------------------------------------------
# DB specific Settings

# Property that determines which Hibernate dialect to use
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

私が間違っていることは何ですか?

アップデート

デバッグsessionFactory.getCurrentSession()の結果:

DEBUG : com.example.model.ArticleDAO - SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])

いくつかのグローバル変数を追加していますが、これがエラーの原因になっているのでしょうか? 私のコントローラーにはメソッドがあります:

@ModelAttribute
public void addGlobalObjects( Map<String, Object> map )
{
    map.put( "section", "blog" );

    SortedMap<Category, Integer> categories = new TreeMap<Category, Integer>();
    for ( Category category : categoryService.list() )
    {
        categories.put( category, articleService.size( category ) );
    }

    Calendar cal = Calendar.getInstance();
    cal.set( Calendar.DAY_OF_MONTH, 1 );

    cal.add( Calendar.MONTH, ARCHIVE_MONTHS * -1 );

    SortedMap<Date, Integer> archive = new TreeMap<Date, Integer>();
    for ( int i = 0; i < ARCHIVE_MONTHS; ++i )
    {
        cal.add( Calendar.MONTH, 1 );
        archive.put( cal.getTime(), articleService.size( cal ) );
    }

    SortedMap<Tag, Integer> tags = new TreeMap<Tag, Integer>();
    for ( Tag tag : tagService.list() )
    {
        tags.put( tag, articleService.size( tag ) );
    }

    map.put( "categories", categories );
    map.put( "archive", archive );
    map.put( "tags", tags );

    map.put( "categoriesSize", categoryService.size() );
    map.put( "tagsSize", tagService.size() );

    map.put( "date", new Date() );
}

更新された記事エンティティについては、上記を参照してください。

更新2

Eager fetching は問題を解決しませんでした - それでも同じ例外:

@ManyToMany( fetch = FetchType.EAGER, cascade = { CascadeType.ALL } )

そして最後に、必要のない重複した記事を取得しています...

更新3

Hibernate.initialize()この例外が発生しています:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session

更新4

get メソッドを次のように変更しました。

@Override
public Article get( int id )
{
    // return ( Article ) sessionFactory.getCurrentSession().load( Article.class, id );
    return ( Article ) sessionFactory.getCurrentSession().createCriteria( Article.class ).add( Restrictions.eq( "id", id ) ).uniqueResult();
}

これは解決策ではありませんが、この問題を処理できないため、一時的にこれを使用します。

私はすでにこれを試しました(ここで述べたように)成功しませんでした(ELExceptionをからError reading 'id' on type ...に変更しましたError reading 'title' on type ...-多分私はそれを間違って使用しましたか?):

@Override
public Article get( int id )
{
    Article ret = ( Article ) sessionFactory.getCurrentSession().load( Article.class, id );
    sessionFactory.getCurrentSession().update( ret );
    return ret;
}

まだ解決策が必要です!

4

3 に答える 3

2

これでうまくいきました!

ArticleDAO.get を変更

@Override
public Article get( int id )
{
    return ( Article ) sessionFactory.getCurrentSession().load( Article.class, id );
}

@Override
public Article get( int id )
{
    Article ret = ( Article ) sessionFactory.getCurrentSession().get( Article.class, id );
    if ( ret == null )
    {
        ret = ( Article ) sessionFactory.getCurrentSession().load( Article.class, id );
    }

    return ret;
}
于 2012-08-01T23:03:01.620 に答える
1

何が問題なのかわかりませんが、ガイドとなるいくつかの質問
-1.メソッドをデバッグできますか

public Article get( int id )

そして、あなたは何のために得るのか見てください

sessionFactory.getCurrentSession()

これは有効なセッションですか?


2. Articleエンティティについて詳しく説明していただけますか?別のエンティティと何らかの関係がありますか?

あなたの問題は私の質問の間のどこかにあると思います。



あなたが提供した情報に従って、私の答えを更新してください-

私が疑ったように、あなたのArticleエンティティは他のエンティティと関係があります。
Articleおよび関連エンティティの熱心なフェッチを実行しません。
ただし、Articleに関連付けられているコレクションを変更しようとします。これは間違ってい
ます私が知る限り、このマップを初期化した場合(Mapインターフェイスを構成するオブジェクトを具体的に割り当ててフィールドに設定することにより)、コレクション(この場合はマップ)を変更できます
(これをフィールドに設定します)。しませんでした-DBから記事を取得すると、Hibernateはそれを初期化しました。PersistentMapについて読んで詳細を参照してください
または、コレクションがフェッチされた場合は、コレクションを変更する必要があります。熱心なフェッチ

についてはこちらをお読みください。 アノテーションなしで熱心なフェッチを実行するHSQLを作成することもできます。HQLを使用してフェッチを実行する方法をここで 読んでください(左結合フェッチを検索してください)。

于 2012-07-29T23:48:57.537 に答える
1

Hibernateを使用しているのでHibernate.initialize()、そのレイジーコレクションを初期化するために呼び出すことができます。

一方、Articleに関連付けられているすべてのアイテムをフェッチし、そのコレクションを置き換えるNamedQueryを作成できます。ただし、このオプションは、コレクションに。の注釈が付いていない場合にのみ可能ですorphanRemoval=true。エンティティを注意深く管理しないと、データベースに一貫性のないエントリが含まれる可能性があるため、注意してください。

于 2012-07-30T20:07:48.063 に答える