0

私は最近タペストリーの学習を始めたばかりで、独自の Celebrity Collector アプリケーションを作成しようとしています。

モックデータベースの代わりにデータベースサポートを提供したいと思うまで、すべてがうまくいきました。

Tapestry 5.3.7 で Hibernate 3.6 を使用しています。

データベースを次のように構成しました。

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:target\database</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password">sa</property>
        <property name="hbm2ddl.auto">create-drop</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
    </session-factory>
</hibernate-configuration>

私のDAOインターフェースと実装は次のようになります。

package com.example.addressbook.data;

import java.util.List;

import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.PostInjection;

import com.example.addressbook.entities.Celebrity;

public interface CelebrityDao {
    @CommitAfter
    int count();

    @CommitAfter
    void add(Celebrity celebrity);

    @CommitAfter
    Celebrity get(long id);

    @CommitAfter
    List<Celebrity> getAll();

    @CommitAfter
    List<Celebrity> getRange(long startIndex, long endIndex);

    @PostInjection
    void prepare();
}

package com.example.addressbook.data.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.example.addressbook.data.CelebrityDao;
import com.example.addressbook.entities.Celebrity;

public class CelebrityDaoImpl implements CelebrityDao {

    @Inject
    protected Session session;

    public void add(Celebrity celebrity) {
        session.persist(celebrity);
    }

    public Celebrity get(long id) {
        Criteria criteria = session.createCriteria(Celebrity.class);
        criteria.add(Restrictions.eq("id", id));

        Celebrity celebrity = (Celebrity) criteria.uniqueResult();

        return celebrity;
    }

    public List<Celebrity> getAll() {
        Criteria criteria = session.createCriteria(Celebrity.class);
        List rawResults = criteria.list();

        List<Celebrity> results = new ArrayList<Celebrity>();

        for (Object object : rawResults) {
            results.add((Celebrity) object);
        }

        return results;
    }

    public List<Celebrity> getRange(long startIndex, long endIndex) {
        Criteria criteria = session.createCriteria(Celebrity.class);
        criteria.add(Restrictions.between("id", startIndex, endIndex));
        List rawResults = criteria.list();

        List<Celebrity> results = new ArrayList<Celebrity>();

        for (Object object : rawResults) {
            results.add((Celebrity) object);
        }

        return results;
    }

    public void prepare() {
 // adding some initial records in the database

    }

    public int count() {
        return getAll().size();
    }

}

私の ShowAll クラスは次のとおりです。

package com.example.addressbook.pages;

import java.text.Format;
import java.util.List;

import org.apache.tapestry5.SelectModel;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.grid.GridDataSource;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.BeanModelSource;

import com.example.addressbook.data.CelebrityDao;
import com.example.addressbook.entities.Celebrity;
import com.example.addressbook.model.User;
import com.example.addressbook.util.CelebrityEncoder;
import com.example.addressbook.util.CelebritySelectModel;
import com.example.addressbook.util.Formats;
import com.example.addressbook.util.HibernateEntityDataSource;

public class ShowAll {
    @SessionState
    private User user;

    private boolean userExists;

    @Inject
    private CelebrityDao dao;

    @InjectPage
    private Details detailsPage;

    @Property
    private Celebrity celebrity;

    @Inject
    private BeanModelSource beanModelSource;

    @Inject
    private Messages messages;

    String onActivate() {
        if (!userExists)
            return "Index";

        return null;
    }

    @OnEvent(component = "detailsLink")
    Object onShowDetails(long id) {
        Celebrity celebrity = dao.get(id);
        detailsPage.setCelebrity(celebrity);

        System.err.println("Requested ID: " + id);
        System.err.println("Result: " + celebrity.getLastName());
        return detailsPage;
    }

    public BeanModel<Celebrity> getModel() {
        return beanModelSource.createDisplayModel(Celebrity.class, messages);
    }

    public List<Celebrity> getAllCelebrities() {
        return this.dao.getAll();
    }

    public Format getDateFormat() {
        return Formats.getDateFormat();
    }

    public User getUser() {
        return user;
    }

    public GridDataSource getCelebritySource() {
        return new HibernateEntityDataSource<Celebrity>(Celebrity.class, dao);
    }

    public SelectModel getCelebrityModel() {
        return new CelebritySelectModel(getAllCelebrities());
    }

    public ValueEncoder<Celebrity> getCelebrityEncoder() {
        return new CelebrityEncoder(dao);
    }

    @Persist
    private Celebrity selectedCelebrity;

    public Celebrity getSelectedCelebrity() {
        return selectedCelebrity;
    }

    public void setSelectedCelebrity(Celebrity selectedCelebrity) {
        this.selectedCelebrity = selectedCelebrity;
    }

    public String getSelectedCelebrityName() {
        if (selectedCelebrity == null) {
            return "";
        }

        return selectedCelebrity.getFirstName() + " " + selectedCelebrity.getLastName();
    }
}

そして、これが私が新しいものを追加する方法です:

package com.example.addressbook.pages;

import org.apache.tapestry5.ioc.annotations.Inject;

import com.example.addressbook.data.CelebrityDao;
import com.example.addressbook.entities.Celebrity;

public class AddCelebrity {

    private Celebrity celebrity;

    @Inject
    private CelebrityDao dao;

    public void onActivate() {
        System.out.println("OnActivate: " + dao.getAll().toString());
        if (celebrity == null) {
            celebrity = new Celebrity();
        }
    }

    public Celebrity getCelebrity() {
        return celebrity;
    }

    public void setCelebrity(Celebrity celebrity) {
        this.celebrity = celebrity;
    }

    Object onSuccess() {
        dao.add(celebrity);
        System.out.println("All celebrities: " + dao.getAll().toString());
        return ShowAll.class;
    }
}

問題は次のとおりです。最初に ShowAll ページにアクセスすると、レコードがデータベースから取得されてレンダリングされます。ページを更新すると、レコードが魔法のように削除され、何も表示されません。データベースが空です (dao.getAll() は空のリストを返します) AddCelebrity ページを介して新しい有名人を追加すると、データベースに挿入されますが、ページが更新されると、魔法が再び発生し、データベースは再び空になります。

DAO インターフェイスと実装を AppModule クラスにバインドしました。

public static void bind(ServiceBinder binder) {
    binder.bind(SupportedLocales.class, SupportedLocalesImpl.class);
    binder.bind(CelebrityDao.class, CelebrityDaoImpl.class);
}

ヘルプ!!:)

4

1 に答える 1

0

答えは、AppModuleクラスに別のメソッドを追加することでした

@Match("*Dao")
public static void adviseTransactions(HibernateTransactionAdvisor advisor,
        MethodAdviceReceiver receiver) {
    advisor.addTransactionCommitAdvice(receiver);
}

@CommitAfterTapestry が実際に私の DAO メソッドに注釈を付けて何かを実行できるようにします。

于 2013-07-24T11:06:17.527 に答える