我一直在尝试从 Tapestry-hibernate 转到 Tapestry-jpa。
我已经按照用户指南http://tapestry.apache.org/integrating-with-jpa.html进行操作,但是,我遇到了一些对我来说未知的异常,我不知道如何解决它。
2013-07-25 12:36:20.608:WARN::failed app: java.lang.RuntimeException: Exception constructing service 'RegistryStartup': Error invoking service contribution method org.apache.tapestry5.jpa.JpaModule.startupEarly(EntityManagerManager, boolean): No persistence providers available for "DemoUnit" after trying the following discovered implementations: NONE
2013-07-25 12:36:20.608:WARN::Failed startup of context org.mortbay.jetty.webapp.WebAppContext@2bbd9de3{/addressbook,C:\Users\eivaore\workspaces\training\addressbook\src\main\webapp}
java.lang.RuntimeException: Exception constructing service 'RegistryStartup': Error invoking service contribution method org.apache.tapestry5.jpa.JpaModule.startupEarly(EntityManagerManager, boolean): No persistence providers available for "DemoUnit" after trying the following discovered implementations: NONE
at org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator.obtainObjectFromCreator(JustInTimeObjectCreator.java:75)
at org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator.createObject(JustInTimeObjectCreator.java:54)
at $Runnable_11a5a7e5614b.delegate(Unknown Source)
at $Runnable_11a5a7e5614b.run(Unknown Source)
at org.apache.tapestry5.ioc.internal.RegistryImpl.performRegistryStartup(RegistryImpl.java:325)
at org.apache.tapestry5.ioc.internal.RegistryWrapper.performRegistryStartup(RegistryWrapper.java:80)
at org.apache.tapestry5.TapestryFilter.init(TapestryFilter.java:118)
at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:97)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:713)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at runjettyrun.Bootstrap.main(Bootstrap.java:97)
2013-07-25 12:36:20.642:INFO::Started SelectChannelConnector@0.0.0.0:8888
我persistence.xml
的位置src/main/resources/META-INF/
如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="DemoUnit" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.logging.level" value="fine"/>
</properties>
</persistence-unit>
</persistence>
我在我的 DAO 类中使用它,如下所示:
package com.example.addressbook.data.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import org.apache.tapestry5.ioc.annotations.PostInjection;
import com.example.addressbook.data.CelebrityDao;
import com.example.addressbook.entities.Celebrity;
import com.example.addressbook.entities.Occupation;
import com.example.addressbook.util.Formats;
public class CelebrityDaoImpl implements CelebrityDao {
@PersistenceContext(unitName = "DemoUnit")
private EntityManager entityManager;
public CelebrityDaoImpl() {
}
public void add(Celebrity celebrity) {
entityManager.persist(celebrity);
}
public Celebrity get(long id) {
return entityManager.find(Celebrity.class, id);
}
public List<Celebrity> getAll() {
return entityManager.createQuery("SELECT c FROM Celebrity",
Celebrity.class).getResultList();
}
public List<Celebrity> getRange(long startIndex, long endIndex) {
TypedQuery<Celebrity> query = entityManager.createQuery(
"SELECT c FROM Celebrity where c.id BETWEEN :idStart AND :idEnd",
Celebrity.class);
query.setParameter("idStart", startIndex);
query.setParameter("idEnd", endIndex);
return query.getResultList();
}
@PostInjection
public void prepare() {
add(new Celebrity("Britney", "Spearce",
Formats.parseDate("12/02/1981"), Occupation.SINGER, "", true));
add(new Celebrity("Bill", "Clinton", Formats.parseDate("08/19/1946"),
Occupation.POLITICIAN, "", true));
add(new Celebrity("Placido", "Domingo",
Formats.parseDate("01/21/1941"), Occupation.SINGER, "", true));
add(new Celebrity("Albert", "Einstein",
Formats.parseDate("03/14/1879"), Occupation.SCIENTIST, "", true));
add(new Celebrity("Ernest", "Hemingway",
Formats.parseDate("07/21/1899"), Occupation.WRITER, "", true));
add(new Celebrity("Luciano", "Pavarotti",
Formats.parseDate("10/12/1935"), Occupation.SINGER, "", true));
add(new Celebrity("Ronald", "Reagan", Formats.parseDate("02/06/1911"),
Occupation.POLITICIAN, "", true));
add(new Celebrity("Pablo", "Picasso", Formats.parseDate("10/25/1881"),
Occupation.ARTIST, "", true));
add(new Celebrity("Blaise", "Pascal", Formats.parseDate("06/19/1623"),
Occupation.SCIENTIST, "", true));
add(new Celebrity("Isaac", "Newton", Formats.parseDate("01/04/1643"),
Occupation.SCIENTIST, "", true));
add(new Celebrity("Antonio", "Vivaldi",
Formats.parseDate("03/04/1678"), Occupation.COMPOSER, "", true));
add(new Celebrity("Niccolo", "Paganini",
Formats.parseDate("10/27/1782"), Occupation.MUSICIAN, "", true));
add(new Celebrity("Johannes", "Kepler",
Formats.parseDate("12/27/1571"), Occupation.SCIENTIST, "", true));
add(new Celebrity("Franz", "Kafka", Formats.parseDate("07/03/1883"),
Occupation.WRITER, "", true));
add(new Celebrity("George", "Gershwin",
Formats.parseDate("09/26/1898"), Occupation.COMPOSER, "", true));
}
public int count() {
return getAll().size();
}
}