2010-05-06 112 views
2

我是Java EE 6的新手,我正在尝试开发非常简单的JAX-RS应用程序。 REST满网页服务正常工作。但是当我运行测试应用程序时,我得到了以下结果。我做错了什么?或者我忘记了任何配置?当然,我创建了一个JNDI,并使用Netbeans 6.8 IDE。最后,谢谢你的任何建议。测试驱动的开发问题

我的实体:


@Entity 
@Table(name = "BOOK") 
@NamedQueries({ 
    @NamedQuery(name = "Book.findAll", query = "SELECT b FROM Book b"), 
    @NamedQuery(name = "Book.findById", query = "SELECT b FROM Book b WHERE b.id = :id"), 
    @NamedQuery(name = "Book.findByTitle", query = "SELECT b FROM Book b WHERE b.title = :title"), 
    @NamedQuery(name = "Book.findByDescription", query = "SELECT b FROM Book b WHERE b.description = :description"), 
    @NamedQuery(name = "Book.findByPrice", query = "SELECT b FROM Book b WHERE b.price = :price"), 
    @NamedQuery(name = "Book.findByNumberofpage", query = "SELECT b FROM Book b WHERE b.numberofpage = :numberofpage")}) 
public class Book implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "ID") 
    private Integer id; 
    @Basic(optional = false) 
    @Column(name = "TITLE") 
    private String title; 
    @Basic(optional = false) 
    @Column(name = "DESCRIPTION") 
    private String description; 
    @Basic(optional = false) 
    @Column(name = "PRICE") 
    private double price; 
    @Basic(optional = false) 
    @Column(name = "NUMBEROFPAGE") 
    private int numberofpage; 

    public Book() 
    { 
    } 

    public Book(Integer id) 
    { 
     this.id = id; 
    } 

    public Book(Integer id, String title, String description, double price, int numberofpage) 
    { 
     this.id = id; 
     this.title = title; 
     this.description = description; 
     this.price = price; 
     this.numberofpage = numberofpage; 
    } 

    public Integer getId() 
    { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public double getPrice() { 
     return price; 
    } 

    public void setPrice(double price) { 
     this.price = price; 
    } 

    public int getNumberofpage() { 
     return numberofpage; 
    } 

    public void setNumberofpage(int numberofpage) { 
     this.numberofpage = numberofpage; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Book)) { 
      return false; 
     } 
     Book other = (Book) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.entity.Book[id=" + id + "]"; 
    } 
} 

我的JUnit测试类:


public class BookTest 
{ 

    private static EntityManager em; 
    private static EntityManagerFactory emf; 

    public BookTest() 
    { 

    } 

    @BeforeClass 
    public static void setUpClass() throws Exception 
    { 
     emf = Persistence.createEntityManagerFactory("E01R01PU"); 
     em = emf.createEntityManager(); 
    } 

    @AfterClass 
    public static void tearDownClass() throws Exception 
    { 
     em.close(); 
     emf.close(); 
    } 

    @Test 
    public void createBook() 
    { 
     Book book = new Book(); 
     book.setId(1); 
     book.setDescription("Mastering the Behavior Driven Development with Ruby on Rails"); 
     book.setTitle("Mastering the BDD"); 
     book.setPrice(25.9f); 
     book.setNumberofpage(1029); 

     em.persist(book); 

     assertNotNull("ID should not be null", book.getId()); 
    } 
} 

我的persistence.xml


<persistence> 
    <persistence-unit name="E01R01PU" transaction-type="JTA"> 
    <jta-data-source>BookstoreJNDI</jta-data-source> 
    <properties /> 
    </persistence-unit> 
</persistence> 
 

和异常是:


May 7, 2009 11:10:37 AM org.hibernate.validator.util.Version 
INFO: Hibernate Validator bean-validator-3.0-JBoss-4.0.2 
May 7, 2009 11:10:37 AM org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA 
INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver. 
[EL Info]: 2009-05-07 11:10:37.531--ServerSession(13671123)--EclipseLink, version: Eclipse Persistence Services - 2.0.0.v20091127-r5931 
May 7, 2009 11:10:40 AM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates 
INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate 
May 7, 2009 11:10:43 AM com.sun.enterprise.connectors.ActiveRAFactory createActiveResourceAdapter 
SEVERE: rardeployment.class_not_found 
May 7, 2009 11:10:43 AM com.sun.enterprise.connectors.ActiveRAFactory createActiveResourceAdapter 
SEVERE: 
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR 
     at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:104) 
     at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:216) 
     at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:352) 
     at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:106) 
     at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304) 
     at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:472) 
     at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:437) 
     at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:569) 
     at javax.naming.InitialContext.lookup(InitialContext.java:396) 
     at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110) 
     at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94) 
     at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162) 
     at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228) 
     at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195) 
     at com.entity.BookTest.setUpClass(BookTest.java:31) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:220) 
     at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888) 
Caused by: java.lang.ClassNotFoundException: com.sun.gjc.spi.ResourceAdapter 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:200) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:251) 
     at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:96) 
     ... 32 more 
[EL Severe]: 2009-05-07 11:10:43.937--ServerSession(13671123)--Local Exception Stack: 
Exception [EclipseLink-7060] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: Cannot acquire data source [BookstoreJNDI]. 
Internal Exception: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]] 
     at org.eclipse.persistence.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:451) 
     at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:116) 
     at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94) 
     at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162) 
     at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228) 
     at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:368) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207) 
     at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195) 
     at com.entity.BookTest.setUpClass(BookTest.java:31) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:220) 
     at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:515) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1031) 
     at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:888) 
Caused by: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]] 
     at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:442) 
     at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:569) 
     at javax.naming.InitialContext.lookup(InitialContext.java:396) 
     at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:110) 
     ... 23 more 
Caused by: javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR] 
     at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:109) 
     at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304) 
     at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:472) 
     at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:437) 
     ... 26 more 
Caused by: com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR 
     at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:104) 
     at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:216) 
     at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:352) 
     at com.sun.enterprise.resource.naming.ConnectorObjectFactory.getObjectInstance(ConnectorObjectFactory.java:106) 
     ... 29 more 
Caused by: java.lang.ClassNotFoundException: com.sun.gjc.spi.ResourceAdapter 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:200) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:251) 
     at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:96) 
     ... 32 more 

Exception Description: Cannot acquire data source [BookstoreJNDI]. 
Internal Exception: javax.naming.NamingException: Lookup failed for 'BookstoreJNDI' in SerialContext ,orb'sInitialHost=localhost,orb'sInitialPort=3700 [Root exception is javax.naming.NamingException: Failed to look up ConnectorDescriptor from JNDI [Root exception is com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Error in creating active RAR]]) 

回答

1

您的输出中首次出现“由java.lang.ClassNotFoundException:com.sun.gjc.spi.ResourceAdapter ”错误引发的错误。这应该是你应该修复的第一件事(缺少一些东西)。另一方面,我在你的书类中看到了很多注释,这在大多数情况下是不需要的。特别是那些列名。顺便说一句:为什么你注释的属性,而不是getters?你已经覆盖了equals(),但没有真正实现它(仅适用于Id字段,那么其他字段呢?)。如果你需要覆盖equals,你也必须重写hashCode。让IDE创建它会简单得多。

+0

诠释属性(你甚至可以使用JPA 2.0混合属性和getter的注解)。另外,对于JPA,当前的'equals'实现是正确的(如果两本书具有相同的PK,则它们应该与JPA的观点相同),并且OP确实实现了'hashCode'。使用PK而不是商业密钥是有争议的,但这是另一回事。 – 2010-05-06 06:42:59

3

首先,您在类路径中缺少一些JAR,我的建议是添加$GF_HOME/modules/gf-client.jar(不要将JAR复制到您的项目中,直接指向它)。

其次,你的测试将不会在其当前状态传递,它缺少某些部分:

  • persist需求的事务中被称为
  • 需要flush获得一个ID分配的变化。

这里是一个改进版本,将与自己的EntityManager和一个事务中运行每个测试方法(即在测试方法结束回滚):

public class BookTest { 
    private static EntityManager em; 
    private static EntityManagerFactory emf; 

    @BeforeClass 
    public static void createEntityManagerFactory() { 
     emf = Persistence.createEntityManagerFactory("E01R01PU"); 
    } 

    @AfterClass 
    public static void closeEntityManagerFactory() throws Exception { 
     emf.close(); 
    } 

    @Before 
    public void beginTransaction() { 
     em = emf.createEntityManager(); 
     em.getTransaction().begin(); 
    } 

    @After 
    public void rollbackTransaction() { 
     if (em.getTransaction().isActive()) { 
      em.getTransaction().rollback(); 
     } 

     if (em.isOpen()) { 
      em.close(); 
     } 
    } 

    @Test 
    public void createBook() { 
     Book book = new Book(); 
     book.setId(1); 
     book.setDescription("Mastering the Behavior Driven Development with " + 
          "Ruby on Rails"); 
     book.setTitle("Mastering the BDD"); 
     book.setPrice(25.9f); 
     book.setNumberofpage(1029); 

     em.persist(book); 
     em.flush(); // sync the in-memory changes with the db 
     // now this will pass 
     assertNotNull("ID should not be null", book.getId()); 
    } 
} 

加成:此测试将通过:)

请注意,人们通常更喜欢能够运行测试,而无需启动容器,即不依赖于JNDI。下面是如何配置的EclipseLink连接到服务器模式下运行的Derby数据库,你可以在测试环境中使用一个persistence.xml:在确定

<?xml version="1.0" encoding="UTF-8"?> 
<persistence 
    xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
    version="2.0"> 

    <persistence-unit name="TestPu" transaction-type="RESOURCE_LOCAL"> 
    <class>com.acme.Foo</class> 

    <exclude-unlisted-classes>false</exclude-unlisted-classes> 

    <properties> 
     <!--property name="eclipselink.target-database" value="DERBY"/--> 
     <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/> 
     <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527//path/to/derbyDBs/TestDB;create=true"/> 
     <property name="javax.persistence.jdbc.user" value="APP"/> 
     <property name="javax.persistence.jdbc.password" value="APP"/> 

     <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> 

     <property name="eclipselink.weaving" value="static" /> 

     <property name="eclipselink.debug" value="ALL"/> 
     <property name="eclipselink.logging.level.sql" value="FINEST" /> 
     <property name="eclipselink.logging.level" value="FINEST" /> 
     <property name="eclipselink.logging.level.cache" value="FINEST" /> 
    </properties> 
    </persistence-unit> 
</persistence> 
+0

我遵循你的指示,它工作。但是当我创建REST Web服务时,我无法构建我的项目。以下是消息: app_path \ build-impl.xml:583:该模块尚未部署。 BUILD失败。那么我现在该做什么? – Zeck 2010-05-06 08:06:23

+0

@请接受这个答案并创建另一个问题:)请不要在同一个问题中混合不同的主题。 – 2010-05-06 08:38:03

+0

+1为gf-client.jar,我跑过这个问题试图解决http://stackoverflow.com/questions/3854687;你真的是JEE/Glassfish的唯一专家吗? :) – Kevin 2010-11-07 17:21:38