私は最近タペストリーの学習を始めたばかりで、独自の 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);
}
ヘルプ!!:)