views:

1238

answers:

1

Have been trying the whole day long and googled the ** out of the web ... in vain. You are my last hope:

Here's my code:

The Entity:

package sas.test.model;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Employee {
    @Id private int id;
    private String name;
    private long salary;
    public Employee() {}
    public Employee(int id) { this.id = id; }
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public long getSalary() { return salary; }
    public void setSalary (long salary) { this.salary = salary; }
}

The service class:

package sas.test.dao;

import sas.test.model.Employee;

import javax.persistence.*;
import java.util.List;

public class EmployeeService {

    protected EntityManager em;

    public EmployeeService(EntityManager em) {
        this.em = em;
    }
    public Employee createEmployee(int id, String name, long salary) {
        Employee emp = new Employee(id);

      emp.setName(name);
  emp.setSalary(salary);
  em.persist(emp);
  return emp;
}
  public void removeEmployee(int id) {
      Employee emp = findEmployee(id);
      if (emp != null) {
          em.remove(emp);
      }
  }
  public Employee raiseEmployeeSalary(int id, long raise) {
      Employee emp = em.find(Employee.class, id);
      if (emp != null) {
          emp.setSalary(emp.getSalary() + raise);
      }
      return emp;
  }
  public Employee findEmployee(int id) {
      return em.find(Employee.class, id);
  }

}

And the main class:

package sas.test.main;

import javax.persistence.*;
import java.util.List;
import sas.test.model.Employee;
import sas.test.dao.EmployeeService;


public class ExecuteMe {
    public static void main(String[] args) {
        EntityManagerFactory emf =
                Persistence.createEntityManagerFactory("EmployeeService");
        EntityManager em = emf.createEntityManager();
        EmployeeService service = new EmployeeService(em);

          // create and persist an employee
          em.getTransaction().begin();
          Employee emp = service.createEmployee(158, "John Doe", 45000);
          em.getTransaction().commit();
          System.out.println("Persisted " + emp);
          // find a specific employee
          emp = service.findEmployee(158);
          System.out.println("Found " + emp);
          // find all employees
     //     List<Employee> emps = service.findAllEmployees();
         // for (Employee e : emps)
         //      System.out.println("Found employee: " + e);
          // update the employee
          em.getTransaction().begin();
          emp = service.raiseEmployeeSalary(158, 1000);
          em.getTransaction().commit();
          System.out.println("Updated " + emp);
          // remove an employee
          em.getTransaction().begin();
          service.removeEmployee(158);
          em.getTransaction().commit();
          System.out.println("Removed Employee 158");
          // close the EM and EMF when done
          em.close();
          emf.close();
    }
}

Finally my confs.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
    <modelVersion>4.0.0</modelVersion>
    <groupId>Test_JPA_CRUD</groupId>
    <artifactId>Test_JPA_CRUD</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>Test_JPA_CRUD</name>
    <url>http://maven.apache.org&lt;/url&gt;
    <repositories>


        <repository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net Repository for Maven</name>
            <url>http://download.java.net/maven/2/
            </url>
            <layout>default</layout>
        </repository>


        <repository>
            <id>maven.org</id>
            <name>maven.org Repository</name>
            <url>http://repo1.maven.org/maven2&lt;/url&gt;
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>

        <!--

                <dependency>
                    <groupId>javax</groupId>
                    <artifactId>javaee-api</artifactId>
                    <version>6.0</version>
                </dependency>
        -->
        <!--
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
                                      -->
        <!-- JPA2 provider -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.4.0.GA</version>
        </dependency>

        <!-- JDBC driver -->
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.5.3.0_1</version>
        </dependency>


        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.3.2.GA</version>
        </dependency>
        <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>ejb3-persistence</artifactId>
          <version>3.3.2.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-annotations</artifactId>
            <version>3.4.0.GA</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.5.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- compile with mvn assembly:assembly -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.2</version>
            </plugin>
            <!-- compile with mvn assembly:assembly -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2-beta-2</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>sas.test.main.ExecuteMe</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- Force UTF-8 & Java-Version 1.6 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <!--<encoding>utf-8</encoding>-->
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

and the persistence.xml, which, I promise, is in the classpath of the target:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
             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_1_0.xsd
http://java.sun.com/xml/ns/persistence ">
    <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>sas.test.model.Employee</class>
        <properties>

            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:derby:webdb;create=true"/>


        </properties>
    </persistence-unit>
</persistence>

As you may have noticed from some commented code, I tried both, the Hibernate and the J2EE 6 implementation of JPA2.0, however, both failed. The above-mentioned code ends up with following error:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.UnsupportedOperationException: The user must supply a JDBC connection
 at org.hibernate.connection.UserSuppliedConnectionProvider.getConnection(UserSuppliedConnectionProvider.java:54)
 at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
 at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
 at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)

Any idea what's going wrong? Any "Hello World" maven/JPA2 demo that actually runs? I couldn't get any of those provided by google's search running.

Thanx in advance.

+3  A: 

Hibernate EntityManager 3.4.0.GA is not a JPA 2.0 implementation so it won't support the standardized javax.persistence.* properties in the persistence.xml (hence the exception about no JDBC connection being supplied). For JPA 2.0, you need Hibernate EM 3.5.1-Final. Below a simple POM with the right dependency:

<project>
  ...
  <repositories>
    <repository>
      <id>jboss</id>
      <name>JBoss repository</name>
      <url>http://repository.jboss.org/maven2&lt;/url&gt;
    </repository>
  </repositories>

  <dependencies>
    <!-- JPA API and Hibernate -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.5.1-Final</version>
    </dependency>

    <!-- Logging -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.5.8</version>
    </dependency>

    ...
  </dependencies>
  ...
</project>

And that's all you need, other dependencies will be pulled transitively. Just replace the slf4j binding I'm using with your favorite one.

If you want to use Bean Validation (JSR-303) API and the RI, add (adapt the scope to suit your needs):

<!-- Bean Validation API and RI -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>4.0.2.GA</version>
    <scope>runtime</scope>
</dependency>

I didn't test your code but this will at least fix your POM.

PS: You don't need to specify the persistence provider in your persistence.xml if there is only one on the classpath, you don't need to list entities by default, you don't need to specify the dialect. But this shouldn't hurt.

PPS: Note that javax.persistence:persistence-api:jar:1.0 is an API, not an implementation, it won't do anything by itself (I mean, it's not a replacement for Hibernate, EclipseLink, etc).

Pascal Thivent
Thank you so much! It works! God save stackoverflow and its participators!