Migrated from Hibernate to OpenJPA

This commit is contained in:
Arjen Poutsma
2007-11-10 03:18:44 +00:00
parent 3441b6bb44
commit dff5ba1be5
23 changed files with 290 additions and 657 deletions

View File

@@ -1,35 +0,0 @@
<?xml version="1.0"?>
<project name="spring-ws-airline-sample-jax-ws-client" default="run-hsqldb" xmlns:artifact="urn:maven-artifact-ant">
<target name="init">
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant">
<classpath>
<pathelement location="${basedir}/../../maven-artifact-ant-2.0.4-dep.jar"/>
</classpath>
</typedef>
<artifact:dependencies pathId="classpath">
<dependency groupId="hsqldb" artifactId="hsqldb" version="1.8.0.7"/>
</artifact:dependencies>
</target>
<target name="clean">
<delete>
<fileset dir="${basedir}">
<include name="airline.*"/>
</fileset>
</delete>
</target>
<target name="run-hsqldb" depends="init">
<java classname="org.hsqldb.Server" fork="true" failonerror="true">
<classpath refid="classpath"/>
<arg line="-database.0 airline -dbname.0 airline"/>
</java>
</target>
</project>

View File

@@ -1,4 +1,5 @@
<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">
<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">
<parent>
<artifactId>spring-ws-samples</artifactId>
<groupId>org.springframework.ws</groupId>
@@ -31,153 +32,6 @@
</plugin>
</plugins>
</reporting>
<profiles>
<!-- These three profiles represent the three databases supported by this sample. Refer to the readme.txt
to see how to use them -->
<profile>
<id>hsqldb</id>
<dependencies>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<properties>
<!-- Change these properties to reflect your HSQLDB connection settings -->
<jdbc.driverClassName>org.hsqldb.jdbcDriver</jdbc.driverClassName>
<jdbc.username>sa</jdbc.username>
<jdbc.password />
<jdbc.url>jdbc:hsqldb:hsql://localhost/airline</jdbc.url>
<hibernate.dialect>org.hibernate.dialect.HSQLDialect</hibernate.dialect>
<hibernate.hbm2ddl.auto />
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
<srcFiles>
<srcFile>${basedir}/src/main/sql/hsqldb/airline-schema.sql</srcFile>
<srcFile>${basedir}/src/main/sql/airline-dataload.sql</srcFile>
</srcFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>mysql</id>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
</dependencies>
<properties>
<!-- Change these properties to reflect your MySQL connection settings -->
<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.username>airline</jdbc.username>
<jdbc.password>airline</jdbc.password>
<jdbc.url>jdbc:mysql://localhost/airline</jdbc.url>
<hibernate.dialect>org.hibernate.dialect.MySQLInnoDBDialect</hibernate.dialect>
<hibernate.hbm2ddl.auto />
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
<srcFiles>
<srcFile>${basedir}/src/main/sql/mysql/airline-schema.sql</srcFile>
<srcFile>${basedir}/src/main/sql/airline-dataload.sql</srcFile>
</srcFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>postgresql</id>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.1-407.jdbc3</version>
</dependency>
</dependencies>
<properties>
<!-- Change these properties to reflect your PostgreSQL connection settings -->
<jdbc.driverClassName>org.postgresql.Driver</jdbc.driverClassName>
<jdbc.username>airline</jdbc.username>
<jdbc.password>airline</jdbc.password>
<jdbc.url>jdbc:postgresql://localhost/airline</jdbc.url>
<hibernate.dialect>org.hibernate.dialect.PostgreSQLDialect</hibernate.dialect>
<hibernate.hbm2ddl.auto />
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.1-407.jdbc3</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
<srcFiles>
<srcFile>${basedir}/src/main/sql/postgresql/airline-schema.sql</srcFile>
<srcFile>${basedir}/src/main/sql/airline-dataload.sql</srcFile>
</srcFiles>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<!-- These properties are overriden by the profiles defined above.
The following values are for using an in-memory database, which is used for testing -->
<jdbc.driverClassName>org.hsqldb.jdbcDriver</jdbc.driverClassName>
<jdbc.username>sa</jdbc.username>
<jdbc.password />
<jdbc.url>jdbc:hsqldb:mem:airline</jdbc.url>
<hibernate.dialect>org.hibernate.dialect.HSQLDialect</hibernate.dialect>
<hibernate.hbm2ddl.auto>create-drop</hibernate.hbm2ddl.auto>
</properties>
<pluginRepositories>
<pluginRepository>
<id>java.net</id>
@@ -228,6 +82,23 @@
<schemaDirectory>src/main/webapp/WEB-INF/xsd</schemaDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-classes</phase>
<configuration>
<tasks>
<java classname="org.apache.openjpa.enhance.PCEnhancer"
classpathref="maven.runtime.classpath" dir="target/classes" fork="true"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
@@ -329,26 +200,26 @@
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.3</version>
<version>2.1.5</version>
<scope>runtime</scope>
</dependency>
<!-- DAO dependencies -->
<!-- O/R Mapping dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.2.1.ga</version>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-lib</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-persistence-jdbc</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.4.sp1</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
@@ -369,7 +240,7 @@
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
<scope>test</scope>
<scope>runtime</scope>
</dependency>
<!-- Various dependencies -->
<dependency>
@@ -426,7 +297,7 @@
<dependency>
<groupId>org.acegisecurity</groupId>
<artifactId>acegi-security-tiger</artifactId>
<version>1.0.3</version>
<version>1.0.5</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
@@ -441,12 +312,5 @@
<scope>test</scope>
<version>2.2</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<version>1.2_Java1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -12,28 +12,11 @@ Multiple clients are available, showing interoperability with Axis 1, SAAJ, C#,
2. INSTALLATION
The Airline sample is a normal web application that connects to a database of your choice. By using Maven2 profiles, it
supports three databases: HSQLDB (the easiest to setup), MySQL, or PostgreSQL.
The Airline sample is a normal web application that connects to a HSQLDB database.
To execute the sample with the supplied HSQLDB:
To execute the sample, run "mvn jetty:run" to run the sample in the Jetty6 Web container.
1. Start a command shell in the subdirectory hsqldb, and run "ant". This starts a HSQLDB server with a database named
airline.
2. Run "mvn -P hsqldb sql:execute" to create the schema and insert data into the database.
3. Run "mvn -P hsqldb jetty:run" to run the sample in the Jetty6 Web container.
To execute the sample with MySQL or PostgreSQL:
1. Change the properties in the pom.xml file to reflect your database connection settings. There are three profiles
(one for each supported database), so make sure to edit the right section. The areas to change are indicated with
comments.
2. Run "mvn -P <database> sql:execute", where <database> is "mysql" or "postgresql", to create the schema and insert
data into the database.
3. Run "mvn -P <database> jetty:run", where <database> is "mysql" or "postgresql", to run the sample in the Jetty6
Web container.
To create a war file instead of running in Jetty, follow the steps above, but replace the "jetty:run" with "package" in
the last step.
To create a war file instead of running in Jetty, use "mvn package".
3. THE CLIENTS

View File

@@ -21,6 +21,6 @@ import org.springframework.ws.samples.airline.domain.Ticket;
public interface TicketDao {
Ticket save(Ticket ticket) throws DataAccessException;
void save(Ticket ticket) throws DataAccessException;
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.dao.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.FrequentFlyer;
import org.springframework.ws.samples.airline.domain.ServiceClass;
/**
* A simple class that uses JPA to initialize the database.
*
* @author Arjen Poutsma
* @since 1.1.0
*/
public class DatabaseInitializer implements InitializingBean {
private static final Log logger = LogFactory.getLog(DatabaseInitializer.class);
@PersistenceContext
private EntityManager entityManager;
private Airport amsterdam;
private Airport venice;
private TransactionTemplate transactionTemplate;
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public void afterPropertiesSet() throws Exception {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
logger.info("Initializing Database");
createAirports();
createFlights();
createFrequentFlyers();
}
});
}
private void createAirports() {
amsterdam = new Airport("AMS", "Schiphol Airport", "Amsterdam");
entityManager.persist(amsterdam);
venice = new Airport("VCE", "Marco Polo Airport", "Venice");
entityManager.persist(venice);
}
private void createFlights() {
Flight flight = new Flight();
flight.setNumber("KL1653");
flight.setDepartureTime(new DateTime(2006, 1, 31, 10, 5, 0, 0));
flight.setFrom(amsterdam);
flight.setArrivalTime(new DateTime(2006, 1, 31, 12, 25, 0, 0));
flight.setTo(venice);
flight.setServiceClass(ServiceClass.ECONOMY);
flight.setSeatsAvailable(5);
flight.setMiles(200);
entityManager.persist(flight);
flight = new Flight();
flight.setNumber("KL1654");
flight.setDepartureTime(new DateTime(2006, 2, 5, 12, 40, 0, 0));
flight.setFrom(venice);
flight.setArrivalTime(new DateTime(2006, 2, 5, 14, 15, 0, 0));
flight.setTo(amsterdam);
flight.setServiceClass(ServiceClass.ECONOMY);
flight.setSeatsAvailable(5);
flight.setMiles(200);
entityManager.persist(flight);
}
private void createFrequentFlyers() {
entityManager.persist(new FrequentFlyer("John", "Doe", "john", "changeme"));
}
}

View File

@@ -40,11 +40,11 @@ public class JpaFlightDao implements FlightDao {
String toAirportCode,
Interval interval,
ServiceClass serviceClass) throws DataAccessException {
Query query = entityManager.createQuery("SELECT f FROM Flight f WHERE f.from.code = :from " +
"AND f.to.code = :to AND f.departureTime >= :start AND f.departureTime <= :end AND " +
Query query = entityManager.createQuery("SELECT f FROM Flight f WHERE f.from.code = :fromParam " +
"AND f.to.code = :toParam AND f.departureTime >= :start AND f.departureTime <= :end AND " +
"f.serviceClass = :class");
query.setParameter("from", fromAirportCode);
query.setParameter("to", toAirportCode);
query.setParameter("fromParam", fromAirportCode);
query.setParameter("toParam", toAirportCode);
query.setParameter("start", interval.getStart());
query.setParameter("end", interval.getEnd());
query.setParameter("class", serviceClass);

View File

@@ -30,7 +30,7 @@ public class JpaTicketDao implements TicketDao {
@PersistenceContext
private EntityManager entityManager;
public Ticket save(Ticket ticket) throws DataAccessException {
return entityManager.merge(ticket);
public void save(Ticket ticket) throws DataAccessException {
entityManager.persist(ticket);
}
}

View File

@@ -27,7 +27,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import org.apache.openjpa.persistence.Persistent;
import org.joda.time.DateTime;
@Entity
@@ -43,7 +43,7 @@ public class Flight implements Serializable {
private String number;
@Column(name = "DEPARTURE_TIME")
@Type(type = "org.springframework.ws.samples.airline.domain.hibernate.DateTimeUserType")
@Persistent
private DateTime departureTime;
@ManyToOne
@@ -51,7 +51,7 @@ public class Flight implements Serializable {
private Airport from;
@Column(name = "ARRIVAL_TIME")
@Type(type = "org.springframework.ws.samples.airline.domain.hibernate.DateTimeUserType")
@Persistent
private DateTime arrivalTime;
@ManyToOne
@@ -160,11 +160,7 @@ public class Flight implements Serializable {
if (!departureTime.equals(flight.departureTime)) {
return false;
}
if (!number.equals(flight.number)) {
return false;
}
return true;
return number.equals(flight.number);
}
public int hashCode() {

View File

@@ -31,7 +31,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import org.apache.openjpa.persistence.Persistent;
import org.joda.time.LocalDate;
@Entity
@@ -43,7 +43,7 @@ public class Ticket implements Serializable {
private Long id;
@Column(name = "ISSUE_DATE")
@Type(type = "org.springframework.ws.samples.airline.domain.hibernate.LocalDateUserType")
@Persistent
private LocalDate issueDate;
@ManyToOne

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.hibernate;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import org.joda.time.DateTime;
/** @author Arjen Poutsma */
public class DateTimeUserType implements UserType {
public int[] sqlTypes() {
return new int[]{Types.TIMESTAMP};
}
public Class returnedClass() {
return DateTime.class;
}
public boolean isMutable() {
return false;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y || !(x == null || y == null) && x.equals(y);
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Timestamp timestamp = rs.getTimestamp(names[0]);
if (rs.wasNull()) {
return null;
}
return new DateTime(timestamp);
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.TIMESTAMP);
}
else {
DateTime dateTime = (DateTime) value;
Timestamp timestamp = new Timestamp(dateTime.getMillis());
st.setTimestamp(index, timestamp);
}
}
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.hibernate;
import java.io.Serializable;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.type.LiteralType;
import org.hibernate.usertype.UserType;
import org.joda.time.LocalDate;
public class LocalDateUserType implements UserType, LiteralType {
public int[] sqlTypes() {
return new int[]{Types.DATE};
}
public Class returnedClass() {
return LocalDate.class;
}
public boolean isMutable() {
return false;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y || !(x == null || y == null) && x.equals(y);
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Date sqlDate = rs.getDate(names[0]);
if (rs.wasNull()) {
return null;
}
return new LocalDate(sqlDate.getTime());
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.DATE);
}
else {
LocalDate localDate = (LocalDate) value;
Date sqlDate = new Date(localDate.toDateMidnight().getMillis());
st.setDate(index, sqlDate);
}
}
public String objectToSQLString(Object value, Dialect dialect) throws Exception {
LocalDate localDate = (LocalDate) value;
return localDate.toString();
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.openjpa;
import java.sql.Timestamp;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.joda.time.DateTime;
/**
* @author Arjen Poutsma
* @since 1.1.0
*/
public class DateTimeValueHandler extends AbstractValueHandler {
private static final DateTimeValueHandler instance = new DateTimeValueHandler();
public static DateTimeValueHandler getInstance() {
return instance;
}
public Column[] map(ValueMapping vm, String name, ColumnIO io, boolean adapt) {
Column col = new Column();
col.setName(name);
col.setJavaType(JavaSQLTypes.TIMESTAMP);
return new Column[]{col};
}
public Object toDataStoreValue(ValueMapping valueMapping, Object val, JDBCStore jdbcStore) {
return val == null ? null : new Timestamp(((DateTime) val).getMillis());
}
public Object toObjectValue(ValueMapping valueMapping, Object val) {
return val == null ? null : new DateTime(val);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.airline.domain.openjpa;
import java.sql.Date;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.joda.time.LocalDate;
/**
* @author Arjen Poutsma
* @since 1.1.0
*/
public class LocalDateValueHandler extends AbstractValueHandler {
public Column[] map(ValueMapping vm, String name, ColumnIO io, boolean adapt) {
Column col = new Column();
col.setName(name);
col.setJavaType(JavaSQLTypes.DATE);
return new Column[]{col};
}
public Object toDataStoreValue(ValueMapping valueMapping, Object val, JDBCStore jdbcStore) {
return val == null ? null : new Date(((LocalDate) val).toDateMidnight().getMillis());
}
public Object toObjectValue(ValueMapping valueMapping, Object val) {
return val == null ? null : new LocalDate(val);
}
}

View File

@@ -91,7 +91,8 @@ public class AirlineServiceImpl implements AirlineService {
}
flight.substractSeats(passengers.size());
flightDao.update(flight);
return ticketDao.save(ticket);
ticketDao.save(ticket);
return ticket;
}
public Flight getFlight(Long id) throws NoSuchFlightException {

View File

@@ -1,9 +1,9 @@
<?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"
<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_1_0.xsd"
version="1.0">
<persistence-unit name="airline">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.springframework.ws.samples.airline.domain.Airport</class>
<class>org.springframework.ws.samples.airline.domain.Flight</class>
<class>org.springframework.ws.samples.airline.domain.FrequentFlyer</class>

View File

@@ -1,6 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.logger.org.springframework.xml=DEBUG
log4j.logger.openjpa=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

View File

@@ -1,9 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="flightDao" class="org.springframework.ws.samples.airline.dao.jpa.JpaFlightDao">
@@ -25,13 +22,26 @@
</description>
</bean>
<bean class="org.springframework.ws.samples.airline.dao.jpa.DatabaseInitializer">
<property name="transactionManager" ref="transactionManager"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="airline"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.OpenJpaDialect"/>
</property>
<property name="jpaProperties">
<util:properties location="classpath:org/springframework/ws/samples/airline/dao/jpa/hibernate.properties"/>
<props>
<prop key="openjpa.Log">commons</prop>
<prop key="openjpa.jdbc.SynchronizeMappings">buildSchema</prop>
<prop key="openjpa.jdbc.MappingDefaults">
FieldStrategies='org.joda.time.DateTime=org.springframework.ws.samples.airline.domain.openjpa.DateTimeValueHandler,
org.joda.time.LocalDate=org.springframework.ws.samples.airline.domain.openjpa.LocalDateValueHandler'
</prop>
<prop key="openjpa.jdbc.DBDictionary">org.apache.openjpa.jdbc.sql.HSQLDictionary</prop>
</props>
</property>
</bean>
@@ -40,14 +50,10 @@
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:org/springframework/ws/samples/airline/dao/jdbc.properties"/>
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:airline"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">

View File

@@ -1,9 +0,0 @@
INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('AMS', 'Schiphol Airport', 'Amsterdam');
INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('VCE', 'Marco Polo Airport', 'Venice');
INSERT INTO FLIGHT(ID, NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) VALUES (1,'KL1653','2006-01-31 10:05:00', 'AMS', '2006-01-31 12:25:00', 'VCE', 'ECONOMY', 5, 200);
INSERT INTO FLIGHT(ID, NUMBER, DEPARTURE_TIME, FROM_AIRPORT_CODE, ARRIVAL_TIME, TO_AIRPORT_CODE, SERVICE_CLASS, SEATS_AVAILABLE, MILES) VALUES (2,'KL1654','2006-02-05 12:40:00', 'VCE', '2006-02-05 14:15:00', 'AMS', 'ECONOMY', 5, 200);
INSERT INTO PASSENGER(ID, FIRST_NAME, LAST_NAME) VALUES (1, 'John', 'Doe');
INSERT INTO FREQUENT_FLYER(PASSENGER_ID, USERNAME, PASSWORD, MILES) VALUES (1, 'john', 'changeme', 10);

View File

@@ -1,61 +0,0 @@
DROP TABLE FREQUENT_FLYER IF EXISTS;
DROP TABLE PASSENGER_TICKET IF EXISTS;
DROP TABLE PASSENGER IF EXISTS;
DROP TABLE TICKET IF EXISTS;
DROP TABLE FLIGHT IF EXISTS;
DROP TABLE AIRPORT IF EXISTS;
CREATE TABLE AIRPORT (
CODE char(3) NOT NULL,
NAME varchar(20) NOT NULL,
CITY varchar(255) NOT NULL,
PRIMARY KEY (CODE)
);
CREATE TABLE FLIGHT (
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
NUMBER VARCHAR(20) NOT NULL,
DEPARTURE_TIME TIMESTAMP NOT NULL,
FROM_AIRPORT_CODE CHAR(3) NOT NULL,
ARRIVAL_TIME TIMESTAMP NOT NULL,
TO_AIRPORT_CODE CHAR(3) NOT NULL,
SEATS_AVAILABLE INT NOT NULL,
SERVICE_CLASS VARCHAR(10) NOT NULL,
MILES INT NOT NULL,
PRIMARY KEY (ID),
UNIQUE (NUMBER, DEPARTURE_TIME),
CONSTRAINT FK_FLIGHT_AIRPORT_FROM FOREIGN KEY (FROM_AIRPORT_CODE) REFERENCES AIRPORT,
CONSTRAINT FK_FLIGHT_AIRPORT_TO FOREIGN KEY (TO_AIRPORT_CODE) REFERENCES AIRPORT
);
CREATE TABLE TICKET (
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
ISSUE_DATE DATE NOT NULL,
FLIGHT_ID BIGINT NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT FK_TICKET_FLIGHT FOREIGN KEY (FLIGHT_ID) REFERENCES FLIGHT
);
CREATE TABLE PASSENGER (
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30),
PRIMARY KEY (ID)
);
CREATE TABLE PASSENGER_TICKET (
TICKET_ID BIGINT NOT NULL,
PASSENGER_ID BIGINT NOT NULL,
PRIMARY KEY (TICKET_ID, PASSENGER_ID),
CONSTRAINT PASSENGER_TICKET_TICKET FOREIGN KEY (TICKET_ID) REFERENCES TICKET,
CONSTRAINT PASSENGER_TICKET_PASSENGER FOREIGN KEY (PASSENGER_ID) REFERENCES PASSENGER
);
CREATE TABLE FREQUENT_FLYER (
PASSENGER_ID BIGINT NOT NULL,
MILES INTEGER,
PASSWORD VARCHAR(255),
USERNAME VARCHAR(255),
PRIMARY KEY (PASSENGER_ID),
CONSTRAINT FREQUENT_FLYER_PASSENGER FOREIGN KEY (PASSENGER_ID) REFERENCES PASSENGER
)

View File

@@ -1,56 +0,0 @@
USE AIRLINE;
DROP TABLE IF EXISTS FREQUENT_FLYER;
DROP TABLE IF EXISTS PASSENGER_TICKET;
DROP TABLE IF EXISTS PASSENGER;
DROP TABLE IF EXISTS TICKET;
DROP TABLE IF EXISTS FLIGHT;
DROP TABLE IF EXISTS AIRPORT;
CREATE TABLE AIRPORT (
CODE CHAR(3) NOT NULL PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
CITY VARCHAR(20) NOT NULL
) TYPE=INNODB;
CREATE TABLE FLIGHT (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
NUMBER VARCHAR(20) NOT NULL,
DEPARTURE_TIME DATETIME NOT NULL,
FROM_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
ARRIVAL_TIME DATETIME NOT NULL,
TO_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
SERVICE_CLASS VARCHAR(10) NOT NULL,
SEATS_AVAILABLE INT(4) UNSIGNED NOT NULL,
MILES INT(4) UNSIGNED NOT NULL,
UNIQUE KEY IDX_NUMBER_DEPARTURE_TIME (NUMBER, DEPARTURE_TIME)
) TYPE=INNODB;
CREATE TABLE TICKET (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
ISSUE_DATE DATE NOT NULL,
FLIGHT_ID INT(4) UNSIGNED NOT NULL REFERENCES FLIGHT(ID)
) TYPE=INNODB;
CREATE TABLE PASSENGER (
ID INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30)
) TYPE=INNODB;
CREATE TABLE PASSENGER_TICKET (
PASSENGER_ID INT(4) UNSIGNED NOT NULL REFERENCES PASSENGER(ID),
TICKET_ID INT(4) UNSIGNED NOT NULL REFERENCES TICKET(ID)
) TYPE=INNODB;
CREATE TABLE FREQUENT_FLYER (
PASSENGER_ID INT(4) UNSIGNED NOT NULL PRIMARY KEY REFERENCES PASSENGER(ID),
USERNAME VARCHAR(10) NOT NULL,
PASSWORD VARCHAR(10) NOT NULL,
MILES INT(4) UNSIGNED NOT NULL,
UNIQUE KEY IDX_USERNAME (USERNAME)
) TYPE=INNODB;

View File

@@ -1,50 +0,0 @@
DROP TABLE FREQUENT_FLYER;
DROP TABLE PASSENGER_TICKET;
DROP TABLE PASSENGER;
DROP TABLE TICKET;
DROP TABLE FLIGHT;
DROP TABLE AIRPORT;
CREATE TABLE AIRPORT (
CODE CHAR(3) NOT NULL PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
CITY VARCHAR(20) NOT NULL
);
CREATE TABLE FLIGHT (
ID BIGSERIAL NOT NULL PRIMARY KEY,
NUMBER VARCHAR(20) NOT NULL,
DEPARTURE_TIME TIMESTAMP NOT NULL,
FROM_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
ARRIVAL_TIME TIMESTAMP NOT NULL,
TO_AIRPORT_CODE CHAR(3) NOT NULL REFERENCES AIRPORT(CODE),
SERVICE_CLASS VARCHAR(10) NOT NULL,
SEATS_AVAILABLE INT NOT NULL,
MILES INT NOT NULL,
UNIQUE(NUMBER, DEPARTURE_TIME)
);
CREATE TABLE TICKET (
ID BIGSERIAL NOT NULL PRIMARY KEY,
ISSUE_DATE DATE NOT NULL,
FLIGHT_ID INT NOT NULL REFERENCES FLIGHT(ID)
);
CREATE TABLE PASSENGER (
ID BIGSERIAL NOT NULL PRIMARY KEY,
FIRST_NAME VARCHAR(30),
LAST_NAME VARCHAR(30)
);
CREATE TABLE PASSENGER_TICKET (
PASSENGER_ID INT NOT NULL REFERENCES PASSENGER(ID),
TICKET_ID INT NOT NULL REFERENCES TICKET(ID)
);
CREATE TABLE FREQUENT_FLYER (
PASSENGER_ID INT NOT NULL PRIMARY KEY REFERENCES PASSENGER(ID),
USERNAME VARCHAR(10) NOT NULL,
PASSWORD VARCHAR(10) NOT NULL,
MILES INT NOT NULL,
UNIQUE (USERNAME)
);

View File

@@ -16,25 +16,17 @@
package org.springframework.ws.samples.airline.dao.jpa;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.springframework.test.jpa.AbstractJpaTests;
import org.springframework.ws.samples.airline.dao.TicketDao;
import org.springframework.ws.samples.airline.domain.Airport;
import org.springframework.ws.samples.airline.domain.Flight;
import org.springframework.ws.samples.airline.domain.Passenger;
import org.springframework.ws.samples.airline.domain.ServiceClass;
import org.springframework.ws.samples.airline.domain.Ticket;
public class JpaTicketDaoTest extends AbstractJpaTests {
private TicketDao ticketDao;
private Flight flight;
private Passenger passenger;
public void setTicketDao(TicketDao ticketDao) {
this.ticketDao = ticketDao;
}
@@ -44,23 +36,6 @@ public class JpaTicketDaoTest extends AbstractJpaTests {
return new String[]{"applicationContext-jpa.xml"};
}
@Override
protected void onSetUpBeforeTransaction() throws Exception {
DateTime departureTime = new DateTime(2006, 1, 31, 10, 5, 0, 0, DateTimeZone.UTC);
DateTime arrivalTime = new DateTime(2006, 1, 31, 12, 25, 0, 0, DateTimeZone.UTC);
Airport fromAirport = new Airport("RTM", "Rotterdam Airport", "Rotterdam");
Airport toAirport = new Airport("OSL", "Gardermoen", "Oslo");
flight = new Flight(42L);
flight.setNumber("KL1653");
flight.setDepartureTime(departureTime);
flight.setFrom(fromAirport);
flight.setArrivalTime(arrivalTime);
flight.setTo(toAirport);
flight.setServiceClass(ServiceClass.BUSINESS);
flight.setSeatsAvailable(90);
passenger = new Passenger(42L, "Arjen", "Poutsma");
}
@Override
protected void onSetUpInTransaction() throws Exception {
jdbcTemplate.update("INSERT INTO AIRPORT(CODE, NAME, CITY) VALUES('RTM', 'Rotterdam Airport', 'Rotterdam')");
@@ -71,13 +46,15 @@ public class JpaTicketDaoTest extends AbstractJpaTests {
}
public void testSave() throws Exception {
Passenger passenger = new Passenger("Arjen", "Poutsma");
Flight flight = sharedEntityManager.find(Flight.class, 42L);
Ticket ticket = new Ticket();
ticket.addPassenger(passenger);
ticket.setFlight(flight);
ticket.setIssueDate(new LocalDate());
int startTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET");
int startPassengerCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM PASSENGER");
ticket = ticketDao.save(ticket);
ticketDao.save(ticket);
sharedEntityManager.flush();
assertNotNull("No Id generated", ticket.getId());
int endTicketCount = jdbcTemplate.queryForInt("SELECT COUNT(0) FROM TICKET");

View File

@@ -21,7 +21,6 @@ import java.util.List;
import junit.framework.TestCase;
import static org.easymock.EasyMock.*;
import org.easymock.IAnswer;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.ws.samples.airline.dao.FlightDao;
@@ -68,11 +67,7 @@ public class AirlineServiceImplTest extends TestCase {
expect(flightDaoMock.update(flight)).andReturn(flight);
Ticket ticket = new Ticket();
ticket.setFlight(flight);
expect(ticketDaoMock.save(isA(Ticket.class))).andAnswer(new IAnswer<Ticket>() {
public Ticket answer() throws Throwable {
return (Ticket) getCurrentArguments()[0];
}
});
ticketDaoMock.save(isA(Ticket.class));
replay(flightDaoMock, ticketDaoMock, securityServiceMock);
@@ -97,11 +92,7 @@ public class AirlineServiceImplTest extends TestCase {
expect(securityServiceMock.getFrequentFlyer("john")).andReturn(frequentFlyer);
expect(flightDaoMock.getFlight(flightNumber, departureTime)).andReturn(flight);
expect(flightDaoMock.update(flight)).andReturn(flight);
expect(ticketDaoMock.save(isA(Ticket.class))).andAnswer(new IAnswer<Ticket>() {
public Ticket answer() throws Throwable {
return (Ticket) getCurrentArguments()[0];
}
});
ticketDaoMock.save(isA(Ticket.class));
replay(flightDaoMock, ticketDaoMock, securityServiceMock);