mirror of https://github.com/apache/openjpa.git
Test case that works when enhancement is done at compile time. OPENJPA-684.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@684066 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
122229bb9a
commit
0bbc9463fd
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.models.library;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name="LIBBOOK")
|
||||
public class Book {
|
||||
private static final int WEEKS_TIME_MS = 1000 * 60 * 60 * 24 * 7;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int oid;
|
||||
|
||||
// persistent fields
|
||||
@Basic
|
||||
private String title;
|
||||
|
||||
@Basic
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date dueDate;
|
||||
|
||||
@ManyToOne
|
||||
private Borrower borrower;
|
||||
|
||||
@ManyToMany(mappedBy = "books", cascade = CascadeType.PERSIST)
|
||||
private Set<Subject> subjects;
|
||||
|
||||
protected Book() {
|
||||
// used only by OpenJPA
|
||||
}
|
||||
|
||||
public Book(String title) {
|
||||
if (title != null)
|
||||
title = title.trim();
|
||||
|
||||
if ((title == null) || (title.length() <= 0))
|
||||
throw new IllegalArgumentException("Title cannot be empty or null");
|
||||
|
||||
this.title = title;
|
||||
subjects = new HashSet<Subject>();
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Borrower getBorrower() {
|
||||
return borrower;
|
||||
}
|
||||
|
||||
void setBorrower(Borrower borrower) {
|
||||
if (borrower != null) {
|
||||
this.borrower = borrower;
|
||||
// set the due date, one week from today
|
||||
long one_week_out = System.currentTimeMillis() + WEEKS_TIME_MS;
|
||||
dueDate = new Date(one_week_out);
|
||||
}
|
||||
}
|
||||
|
||||
void clearBorrower() {
|
||||
borrower = null;
|
||||
dueDate = null;
|
||||
}
|
||||
|
||||
public Date getDueDate() {
|
||||
return dueDate;
|
||||
}
|
||||
|
||||
public boolean addSubject(Subject subject) {
|
||||
boolean retv = false;
|
||||
|
||||
if ((subject != null) && subject.addBook(this)) {
|
||||
retv = true;
|
||||
subjects.add(subject);
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
public boolean removeSubject(Subject subject) {
|
||||
boolean retv = false;
|
||||
|
||||
if ((subject != null) && subject.removeBook(this)) {
|
||||
retv = true;
|
||||
subjects.remove(subject);
|
||||
}
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
public List<Subject> getSubjects() {
|
||||
if (subjects == null)
|
||||
return null;
|
||||
return new ArrayList<Subject>(subjects);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "book [" + oid + "] \"" + title + "\""
|
||||
+ ((dueDate == null) ? "" : (" due back: " + dueDate));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the object's persistent identity value to determine equivalence.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
// standard fare
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
// if the oid is 0, then this object is not persistent.
|
||||
// in that case, it cannot be considered equivalent to
|
||||
// other managed or unmanaged objects
|
||||
if (oid == 0)
|
||||
return false;
|
||||
|
||||
if (other instanceof Book) {
|
||||
Book ob = (Book) other;
|
||||
return oid == ob.oid;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.models.library;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name="LIBBORROWER")
|
||||
public class Borrower {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int oid;
|
||||
|
||||
// persistent fields
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "borrower", fetch = FetchType.EAGER)
|
||||
private Set<Book> books;
|
||||
|
||||
@OneToOne(mappedBy = "borrower", cascade = { CascadeType.PERSIST,
|
||||
CascadeType.REMOVE })
|
||||
private Volunteer volunteer;
|
||||
|
||||
protected Borrower() {
|
||||
// used only by OpenJPA
|
||||
}
|
||||
|
||||
public Borrower(String name) {
|
||||
if (name != null)
|
||||
name = name.trim();
|
||||
|
||||
if ((name == null) || (name.length() <= 0))
|
||||
throw new IllegalArgumentException("name cannot be empty or null");
|
||||
|
||||
this.name = name;
|
||||
books = new HashSet<Book>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
if (books == null)
|
||||
return null;
|
||||
return new ArrayList<Book>(books);
|
||||
}
|
||||
|
||||
public void borrowBook(Book book) {
|
||||
if (book == null)
|
||||
return;
|
||||
|
||||
books.add(book);
|
||||
book.setBorrower(this);
|
||||
}
|
||||
|
||||
public void returnBook(Book book) {
|
||||
if (book == null)
|
||||
return;
|
||||
|
||||
books.remove(book);
|
||||
book.clearBorrower();
|
||||
}
|
||||
|
||||
void setVolunteer(Volunteer volunteer) {
|
||||
this.volunteer = volunteer;
|
||||
}
|
||||
|
||||
public Volunteer getVolunteer() {
|
||||
return volunteer;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "borrower [" + oid + "] " + name;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the object's persistent identity value to determine equivalence.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
// standard fare
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
// if the oid is 0, then this object is not persistent.
|
||||
// in that case, it cannot be considered equivalent to
|
||||
// other managed or unmanaged objects
|
||||
if (oid == 0)
|
||||
return false;
|
||||
|
||||
if (other instanceof Borrower) {
|
||||
Borrower ob = (Borrower) other;
|
||||
return oid == ob.oid;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.models.library;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name="LIBSUBJECT")
|
||||
public class Subject {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int oid;
|
||||
|
||||
// persistent fields
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
@ManyToMany
|
||||
private Set<Book> books;
|
||||
|
||||
protected Subject() {
|
||||
// used only by OpenJPA
|
||||
}
|
||||
|
||||
public Subject(String name) {
|
||||
if (name != null)
|
||||
name = name.trim();
|
||||
|
||||
if ((name == null) || (name.length() <= 0))
|
||||
throw new IllegalArgumentException("name cannot be empty or null");
|
||||
|
||||
this.name = name;
|
||||
books = new HashSet<Book>();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return new ArrayList<Book>(books);
|
||||
}
|
||||
|
||||
boolean addBook(Book book) {
|
||||
if (book != null)
|
||||
return books.add(book);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean removeBook(Book book) {
|
||||
if (book != null)
|
||||
return books.remove(book);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "category [" + oid + "] \"" + name + "\"";
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the object's persistent identity value to determine equivalence.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
// standard fare
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
// if the oid is 0, then this object is not persistent.
|
||||
// in that case, it cannot be considered equivalent to
|
||||
// other managed or unmanaged objects
|
||||
if (oid == 0)
|
||||
return false;
|
||||
|
||||
if (other instanceof Subject) {
|
||||
Subject oc = (Subject) other;
|
||||
return oid == oc.oid;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.models.library;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name="LIBVOLUNTEER")
|
||||
public class Volunteer {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int oid;
|
||||
|
||||
@Basic
|
||||
private int hours_per_week;
|
||||
|
||||
@OneToOne(optional = false)
|
||||
private Borrower borrower;
|
||||
|
||||
protected Volunteer() {
|
||||
// used only by OpenJPA
|
||||
}
|
||||
|
||||
public Volunteer(Borrower borrower) {
|
||||
if (borrower == null)
|
||||
throw new IllegalArgumentException("borrower cannot be null");
|
||||
|
||||
if (borrower.getVolunteer() != null)
|
||||
throw new IllegalArgumentException(
|
||||
"borrower is already a volunteer");
|
||||
|
||||
this.borrower = borrower;
|
||||
borrower.setVolunteer(this);
|
||||
}
|
||||
|
||||
public Borrower getBorrower() {
|
||||
return borrower;
|
||||
}
|
||||
|
||||
public int getHoursPerWeek() {
|
||||
return hours_per_week;
|
||||
}
|
||||
|
||||
public void setHoursPerWeek(int hours) {
|
||||
if (hours >= 0)
|
||||
hours_per_week = hours;
|
||||
else
|
||||
throw new IllegalArgumentException("hours must be >= 0");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "volunteer [" + oid + "] \"" + borrower.getName() + "\"";
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the object's persistent identity value to determine equivalence.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
// standard fare
|
||||
if (other == this)
|
||||
return true;
|
||||
|
||||
// if the oid is 0, then this object is not persistent.
|
||||
// in that case, it cannot be considered equivalent to
|
||||
// other managed or unmanaged objects
|
||||
if (oid == 0)
|
||||
return false;
|
||||
|
||||
if (other instanceof Volunteer) {
|
||||
Volunteer ov = (Volunteer) other;
|
||||
return oid == ov.oid;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.spring;
|
||||
|
||||
import org.apache.openjpa.persistence.models.library.*;
|
||||
|
||||
/**
|
||||
* The Spring library example is intended to mirror the behavior of an
|
||||
* application that uses the Spring Framework's JPA transaction manager and
|
||||
* annotations. In this case, the Spring Framework's transactional handling,
|
||||
* through its advice and proxies, causes the entity manager to be closed after
|
||||
* each call to the implementation of the service (a.k.a. DAO) interface. These
|
||||
* observations are based on Spring version 2.5.5.
|
||||
* <p>
|
||||
* It is likely that other containers behave in a similar manner.
|
||||
* <p>
|
||||
* In particular, it mirrors the behavior when there is a Spring annotated
|
||||
* service interface that looks like the following:
|
||||
*
|
||||
* <pre>
|
||||
* (at)Transactional(propagation=Propagation.SUPPORTS)
|
||||
* public interface LibService
|
||||
* {
|
||||
* public Borrower findBorrowerByName(String name);
|
||||
* public Book findBookByTitle(String title);
|
||||
*
|
||||
* (at)Transactional(propagation=Propagation.REQUIRED)
|
||||
* public void borrowBook(Borrower borrower, Book book);
|
||||
*
|
||||
* (at)Transactional(propagation=Propagation.REQUIRED)
|
||||
* public void returnBook(Book book);
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* And there is a Spring configuration file with the following entries:
|
||||
*
|
||||
* <pre>
|
||||
* <bean id="emf"
|
||||
* class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
|
||||
* <property name="persistenceUnitName" value="" />
|
||||
* </bean>
|
||||
*
|
||||
* <!-- enable Spring's support for JPA injection -->
|
||||
* <bean class=
|
||||
* "org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
|
||||
*
|
||||
* <bean id="transactionalService"
|
||||
* class="sample.jpa.service.LibServiceImpl" >
|
||||
* </bean>
|
||||
*
|
||||
* <bean id="transactionManager"
|
||||
* class="org.springframework.orm.jpa.JpaTransactionManager" >
|
||||
* <property name="entityManagerFactory" ref="emf" />
|
||||
* </bean>
|
||||
*
|
||||
* <tx:annotation-driven/>
|
||||
* </pre>
|
||||
* <p>
|
||||
* And the declaration of the entity manager in the service implementation is
|
||||
* annotated with the <b>(at)PersistenceContext</b> annotation.
|
||||
*
|
||||
* @author David Ezzio
|
||||
*/
|
||||
|
||||
public interface LibService {
|
||||
public Borrower findBorrowerByName(String name);
|
||||
|
||||
public Book findBookByTitle(String title);
|
||||
|
||||
public void borrowBook(Borrower borrower, Book book);
|
||||
|
||||
public void returnBook(Book book);
|
||||
|
||||
public void setTransactionalEntityManagerFactory(
|
||||
TransactionalEntityManagerFactory txEMF);
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.spring;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.apache.openjpa.persistence.models.library.*;
|
||||
|
||||
/**
|
||||
* This service uses a transactionally scoped entity manager. It grabs the EM at
|
||||
* the beginning of each business method and closes it at the end of each
|
||||
* business method. Transactional methods start a transaction and either commit
|
||||
* or roll back at the end of the method. This behavior mimics the behavior of
|
||||
* containers that inject transactionally scoped entity managers at the
|
||||
* beginning of each service method and close them at the end.
|
||||
*/
|
||||
public class LibServiceImpl implements LibService {
|
||||
private TransactionalEntityManagerFactory txEMF;
|
||||
|
||||
private void closeEM(EntityManager em) {
|
||||
if (em != null && em.isOpen()) {
|
||||
System.out.println("Closing EM: " + em);
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
||||
private EntityManager openEM() {
|
||||
EntityManager em = txEMF.getTransactionalEntityManager();
|
||||
System.out.println("Opening EM: " + em);
|
||||
return em;
|
||||
}
|
||||
|
||||
private void commit(EntityTransaction tx) {
|
||||
if (tx != null && tx.isActive()) {
|
||||
if (tx.getRollbackOnly())
|
||||
tx.rollback();
|
||||
else
|
||||
tx.commit();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransactionalEntityManagerFactory(
|
||||
TransactionalEntityManagerFactory txEMF) {
|
||||
this.txEMF = txEMF;
|
||||
}
|
||||
|
||||
public Book findBookByTitle(String title) {
|
||||
EntityManager em = null;
|
||||
|
||||
try {
|
||||
em = openEM();
|
||||
|
||||
// check the name passed in
|
||||
if (title != null)
|
||||
title = title.trim();
|
||||
|
||||
if (title == null || title.length() <= 0)
|
||||
throw new IllegalArgumentException(
|
||||
"the title cannot be null or empty");
|
||||
|
||||
// set up the query
|
||||
Query query = em
|
||||
.createQuery("select b from Book b join fetch b.subjects where b.title = :x");
|
||||
query.setParameter("x", title);
|
||||
|
||||
// execute the query and return the books
|
||||
Book retv = (Book) query.getSingleResult();
|
||||
return retv;
|
||||
} finally {
|
||||
closeEM(em);
|
||||
}
|
||||
}
|
||||
|
||||
public Borrower findBorrowerByName(String name) {
|
||||
EntityManager em = null;
|
||||
|
||||
try {
|
||||
em = openEM();
|
||||
|
||||
// check the name passed in
|
||||
if (name != null)
|
||||
name = name.trim();
|
||||
|
||||
if (name == null || name.length() <= 0)
|
||||
throw new IllegalArgumentException(
|
||||
"the name cannot be null or empty");
|
||||
|
||||
// set up the query
|
||||
Query query = em
|
||||
.createQuery("select b from Borrower b where b.name = :x");
|
||||
query.setParameter("x", name);
|
||||
|
||||
// execute the query and return the books
|
||||
Borrower retv = (Borrower) query.getSingleResult();
|
||||
return retv;
|
||||
} finally {
|
||||
closeEM(em);
|
||||
}
|
||||
}
|
||||
|
||||
public void borrowBook(Borrower borrower, Book book) {
|
||||
EntityManager em = null;
|
||||
EntityTransaction tx = null;
|
||||
|
||||
try {
|
||||
em = openEM();
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
|
||||
// do nothing if one of the parameters is null
|
||||
if (borrower == null || book == null)
|
||||
return;
|
||||
|
||||
borrower.borrowBook(book);
|
||||
|
||||
// merge the owner of the relationship
|
||||
em.merge(book);
|
||||
} catch (RuntimeException e) {
|
||||
tx.setRollbackOnly();
|
||||
throw e;
|
||||
} finally {
|
||||
commit(tx);
|
||||
closeEM(em);
|
||||
}
|
||||
}
|
||||
|
||||
public void returnBook(Book book) {
|
||||
EntityManager em = null;
|
||||
EntityTransaction tx = null;
|
||||
|
||||
try {
|
||||
em = openEM();
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
|
||||
// do nothing if the parameter is null
|
||||
if (book == null)
|
||||
return;
|
||||
|
||||
Borrower borrower = book.getBorrower();
|
||||
if (borrower != null) {
|
||||
borrower.returnBook(book);
|
||||
|
||||
// merge the owner of the relationship
|
||||
em.merge(book);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
tx.setRollbackOnly();
|
||||
throw e;
|
||||
} finally {
|
||||
commit(tx);
|
||||
closeEM(em);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.spring;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
import org.apache.openjpa.persistence.models.library.*;
|
||||
|
||||
public class LibTestingService {
|
||||
private EntityManager em;
|
||||
|
||||
public LibTestingService() {
|
||||
}
|
||||
|
||||
public void setEntityManager(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
public void depopulateDB() {
|
||||
// delete everything
|
||||
EntityTransaction tx = em.getTransaction();
|
||||
tx.begin();
|
||||
em.createQuery("delete from Book").executeUpdate();
|
||||
em.createQuery("delete from Borrower").executeUpdate();
|
||||
em.createQuery("delete from Subject").executeUpdate();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
public void repopulateDB() {
|
||||
depopulateDB();
|
||||
|
||||
if (!isDBClean())
|
||||
throw new IllegalStateException("Failed to clean the database");
|
||||
|
||||
EntityTransaction tx = null;
|
||||
|
||||
try {
|
||||
tx = em.getTransaction();
|
||||
tx.begin();
|
||||
|
||||
// create three borrowers Tom, Dick, and Harry
|
||||
Borrower tom = new Borrower("Tom");
|
||||
Borrower dick = new Borrower("Dick");
|
||||
Borrower harry = new Borrower("Harry");
|
||||
|
||||
// make them persistent
|
||||
em.persist(tom);
|
||||
em.persist(dick);
|
||||
em.persist(harry);
|
||||
|
||||
// make Dick a volunteer
|
||||
Volunteer v = new Volunteer(dick);
|
||||
v.setHoursPerWeek(10);
|
||||
|
||||
// create six books
|
||||
Book fishing = new Book("Gone Fishing");
|
||||
Book hunting = new Book("Gone Hunting");
|
||||
Book sailing = new Book("Gone Sailing");
|
||||
Book fighting = new Book("Gone to War");
|
||||
Book visiting = new Book("Gone Visiting");
|
||||
Book working = new Book("Gone to Work");
|
||||
Book sleeping = new Book("Gone to Bed");
|
||||
|
||||
em.persist(fishing);
|
||||
em.persist(hunting);
|
||||
em.persist(sailing);
|
||||
em.persist(fighting);
|
||||
em.persist(visiting);
|
||||
em.persist(working);
|
||||
em.persist(sleeping);
|
||||
|
||||
// create categories for the books
|
||||
Subject outdoors = new Subject("Outdoors");
|
||||
Subject military = new Subject("Military");
|
||||
Subject sport = new Subject("Sportsman");
|
||||
Subject travel = new Subject("Travel");
|
||||
Subject industry = new Subject("Industry");
|
||||
Subject space = new Subject("Space");
|
||||
|
||||
// link the books with the categories
|
||||
fishing.addSubject(outdoors);
|
||||
fishing.addSubject(sport);
|
||||
hunting.addSubject(outdoors);
|
||||
hunting.addSubject(sport);
|
||||
sailing.addSubject(outdoors);
|
||||
sailing.addSubject(travel);
|
||||
fighting.addSubject(military);
|
||||
fighting.addSubject(travel);
|
||||
visiting.addSubject(travel);
|
||||
working.addSubject(industry);
|
||||
|
||||
// this Subject has no books
|
||||
em.persist(space);
|
||||
|
||||
// borrow some books
|
||||
tom.borrowBook(fishing);
|
||||
dick.borrowBook(hunting);
|
||||
dick.borrowBook(sailing);
|
||||
harry.borrowBook(working);
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
} catch (RuntimeException e) {
|
||||
System.err.println("Unable to repopulate the database");
|
||||
System.err.println("Caught exception: " + e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
throw e;
|
||||
} finally {
|
||||
if (tx != null && tx.isActive()) {
|
||||
tx.rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDBClean() {
|
||||
// Do a series of counts
|
||||
// (Avoid any problem in generating a Cartesian join)
|
||||
long count = 0;
|
||||
count += (Long) em.createQuery("select count(b) from Book b")
|
||||
.getSingleResult();
|
||||
count += (Long) em.createQuery("select count(b) from Borrower b")
|
||||
.getSingleResult();
|
||||
count += (Long) em.createQuery("select count(v) from Volunteer v")
|
||||
.getSingleResult();
|
||||
count += (Long) em.createQuery("select count(s) from Subject s")
|
||||
.getSingleResult();
|
||||
return count <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the Service. The method is idempotent. It may be called multiple
|
||||
* times without ill effect.
|
||||
*/
|
||||
public void close() {
|
||||
if (em != null && em.isOpen()) {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
package org.apache.openjpa.persistence.spring;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.openjpa.persistence.*;
|
||||
import org.apache.openjpa.persistence.models.library.*;
|
||||
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
|
||||
|
||||
public class TestLibService extends SingleEMFTestCase
|
||||
implements TransactionalEntityManagerFactory {
|
||||
|
||||
private static EnumSet<AutoDetachType> txScope =
|
||||
EnumSet.allOf(AutoDetachType.class);
|
||||
|
||||
private LibService service;
|
||||
|
||||
public EntityManager getTransactionalEntityManager() {
|
||||
// return a transactionally scoped entity manager
|
||||
OpenJPAEntityManager em = emf.createEntityManager();
|
||||
em.setAutoDetach(txScope);
|
||||
return em;
|
||||
}
|
||||
|
||||
public void setUp() {
|
||||
// declare the library model classes
|
||||
super.setUp(Book.class, Borrower.class, Subject.class, Volunteer.class);
|
||||
|
||||
// put golden data in database
|
||||
LibTestingService libTestingService = new LibTestingService();
|
||||
libTestingService.setEntityManager(emf.createEntityManager());
|
||||
libTestingService. repopulateDB();
|
||||
libTestingService.close();
|
||||
|
||||
// create the LibService
|
||||
service = new LibServiceImpl();
|
||||
service.setTransactionalEntityManagerFactory(this);
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
service = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using known data, test the LibraryService.findBookByTitle() method and
|
||||
* verify the information returned.
|
||||
*/
|
||||
public void testFindBookByTitle() {
|
||||
String title = "Gone Sailing";
|
||||
String qTitle = "\"" + title + "\"";
|
||||
String bName = "Dick";
|
||||
|
||||
try {
|
||||
// find the book
|
||||
Book book = service.findBookByTitle(title);
|
||||
assertNotNull("could not find the book " + qTitle, book);
|
||||
assertEquals("the book found was not the book " + qTitle, title,
|
||||
book.getTitle());
|
||||
|
||||
// get the book's borrower
|
||||
Borrower borrower = book.getBorrower();
|
||||
assertNotNull("could not find the borrower " + bName, borrower);
|
||||
assertEquals("the borrower found was not " + bName, bName,
|
||||
borrower.getName());
|
||||
|
||||
// get the borrower's volunteer status
|
||||
Volunteer volunteer = borrower.getVolunteer();
|
||||
assertNotNull("could not find " + bName + "'s volunteer status",
|
||||
volunteer);
|
||||
assertNotNull("could not find the reference from " + bName
|
||||
+ "'s volunteer status back to " + bName,
|
||||
volunteer.getBorrower() == borrower);
|
||||
|
||||
// get the book's subjects
|
||||
List<Subject> subjects = book.getSubjects();
|
||||
assertNotNull("no subjects for the book " + qTitle, subjects);
|
||||
assertEquals(
|
||||
"unexpected number of subjects for the book " + qTitle, 2,
|
||||
subjects.size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Unable to findBookByTitle");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using known data, test the LibraryService.findBorrowerByName method and
|
||||
* verify the information returned.
|
||||
*/
|
||||
public void testFindBorrowerByName() {
|
||||
String bName = "Harry";
|
||||
try {
|
||||
Borrower harry = service.findBorrowerByName(bName);
|
||||
assertNotNull("Could not find " + bName, harry);
|
||||
assertEquals("the borrower found is not " + bName, bName,
|
||||
harry.getName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Unable to find borrower by name");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Using known data, test the LibraryService.borrowBook() operation.
|
||||
* <ul>
|
||||
* <li>Can we find Tom, and has he borrowed one book?</li>
|
||||
* <li>Can we find the book entitled "Gone Visiting"?</li>
|
||||
* <li>After Tom borrows the new book, has he borrowed two books?</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testBorrowBook() {
|
||||
String bName = "Tom";
|
||||
String title = "Gone Visiting";
|
||||
|
||||
try {
|
||||
// find the borrower Tom
|
||||
Borrower borrower = service.findBorrowerByName(bName);
|
||||
assertNotNull("Could not find " + bName, borrower);
|
||||
List<Book> books = borrower.getBooks();
|
||||
assertEquals(bName + " has borrowed an unexpected number of books",
|
||||
1, (books == null ? 0 : borrower.getBooks().size()));
|
||||
|
||||
// find the book "Gone Visiting"
|
||||
Book book = service.findBookByTitle(title);
|
||||
assertNotNull("Could not find the book " + title, book);
|
||||
|
||||
// have Tom borrow the book
|
||||
service.borrowBook(borrower, book);
|
||||
List<Book> borrowedBooks = borrower.getBooks();
|
||||
assertEquals("Unexpected number of books borrowed", 2,
|
||||
borrowedBooks.size());
|
||||
|
||||
// Verify that the update is in the database
|
||||
borrower = service.findBorrowerByName(bName);
|
||||
assertNotNull("Could not find " + bName, borrower);
|
||||
List<Book> booksBorrowed2 = borrower.getBooks();
|
||||
assertEquals(bName + " has borrowed an unexpected number of books",
|
||||
2, booksBorrowed2.size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Unable to borrow a book");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the LibraryService.returnBook() operation, etc.
|
||||
*/
|
||||
public void testReturnBook() {
|
||||
String bName = "Harry";
|
||||
|
||||
try {
|
||||
// find the borrower Harry
|
||||
Borrower borrower = service.findBorrowerByName(bName);
|
||||
assertNotNull("Could not find " + bName, borrower);
|
||||
List<Book> books = borrower.getBooks();
|
||||
assertEquals(bName + " has borrowed an unexpected number of books",
|
||||
1, (books == null ? 0 : borrower.getBooks().size()));
|
||||
|
||||
// find the one book Harry has borrowed
|
||||
Book book = borrower.getBooks().get(0);
|
||||
service.returnBook(book);
|
||||
|
||||
// Verify that the update is in the database
|
||||
borrower = service.findBorrowerByName(bName);
|
||||
assertNotNull("Could not find " + bName, borrower);
|
||||
assertEquals(bName + " has borrowed an unexpected number of books",
|
||||
0, borrower.getBooks().size());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Unable to return a book");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.apache.openjpa.persistence.spring;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
public interface TransactionalEntityManagerFactory {
|
||||
public EntityManager getTransactionalEntityManager();
|
||||
}
|
Loading…
Reference in New Issue