我最近才开始学习 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);
}
帮助!!:)