0

我最近才开始学习 Tapestry,尝试制作自己的 Celebrity Collector 应用程序。

一切正常,直到我想提供数据库支持而不是模拟数据库。

我正在使用 Hibernate 3.6 和 Tapestry 5.3.7。

我已经像这样配置了我的数据库:

<!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 页面添加一个新名人时,它被插入到数据库中,但随着页面的刷新,魔法再次发生,数据库再次为空。

我在 AppModule 类中绑定了我的 DAO 接口和实现:

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);
}

所以 Tapestry 实际上可以@CommitAfter对我的 DAO 方法进行注释。

于 2013-07-24T11:06:17.527 回答