コードはこれです:
DB:
人物(ID、名前)
Phonenumbers(number, id_persons) FK id_person は Persons(id) を参照します
Java コード:
package com.app.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.jboss.resteasy.annotations.providers.jaxb.JAXBConfig;
@Entity
@Table(name = "phonenumbers", catalog = "test")
public class Phonenumbers implements java.io.Serializable {
private static final long serialVersionUID = -8122359598003938895L;
private String number;
private Persons persons;
public Phonenumbers() {
}
public Phonenumbers(String number) {
this.number = number;
}
public Phonenumbers(String number, Persons persons) {
this.number = number;
this.persons = persons;
}
@Id
@Column(name = "number", unique = true, nullable = false, length = 20)
public String getNumber() {
return this.number;
}
public void setNumber(String number) {
this.number = number;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_person")
public Persons getPersons() {
return this.persons;
}
public void setPersons(Persons persons) {
this.persons = persons;
}
}
package com.app.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "persons", catalog = "test")
public class Persons implements java.io.Serializable {
private static final long serialVersionUID = -3247756369663156186L;
private Integer id;
private String name;
private Set<Phonenumbers> phonenumberses = new HashSet<Phonenumbers>(0);
public Persons() {
}
public Persons(String name) {
this.name = name;
}
public Persons(String name, Set<Phonenumbers> phonenumberses) {
this.name = name;
this.phonenumberses = phonenumberses;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name", nullable = false, length = 50)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "persons")
public Set<Phonenumbers> getPhonenumberses() {
return this.phonenumberses;
}
public void setPhonenumberses(Set<Phonenumbers> phonenumberses) {
this.phonenumberses = phonenumberses;
}
}
package com.app.dao;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.app.model.Phonenumbers;
@Stateless
public class PhonenumbersHome {
private static final Log log = LogFactory.getLog(PhonenumbersHome.class);
@PersistenceContext(unitName="PhoneBook", type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
public void persist(Phonenumbers transientInstance) {
log.debug("persisting Phonenumbers instance");
try {
entityManager.persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void remove(Phonenumbers persistentInstance) {
log.debug("removing Phonenumbers instance");
try {
entityManager.remove(persistentInstance);
log.debug("remove successful");
} catch (RuntimeException re) {
log.error("remove failed", re);
throw re;
}
}
public Phonenumbers merge(Phonenumbers detachedInstance) {
log.debug("merging Phonenumbers instance");
try {
Phonenumbers result = entityManager.merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public Phonenumbers findById(String id) {
log.debug("getting Phonenumbers instance with id: " + id);
try {
Phonenumbers instance = entityManager.find(Phonenumbers.class, id);
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
package com.app.dao;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.app.model.Persons;
@Stateless
public class PersonsHome {
private static final Log log = LogFactory.getLog(PersonsHome.class);
@PersistenceContext(unitName="PhoneBook", type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
public void persist(Persons transientInstance) {
log.debug("persisting Persons instance");
try {
entityManager.persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void remove(Persons persistentInstance) {
log.debug("removing Persons instance");
try {
entityManager.remove(persistentInstance);
log.debug("remove successful");
} catch (RuntimeException re) {
log.error("remove failed", re);
throw re;
}
}
public Persons merge(Persons detachedInstance) {
log.debug("merging Persons instance");
try {
Persons result = entityManager.merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public Persons findById(Integer id) {
log.debug("getting Persons instance with id: " + id);
try {
Persons instance = entityManager.find(Persons.class, id);
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
package com.app.ws;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import com.app.dao.PersonsHome;
import com.app.model.Persons;
@Path("/persons")
public class PersonsResources {
@EJB
private PersonsHome ph;
@GET()
@Produces("application/json")
@Path("/{id}")
public Persons getPerson(@PathParam("id") int id) {
try{
Context cx = new InitialContext();
ph = (PersonsHome)cx.lookup("java:module/PersonsHome");
}catch(Exception e){
e.printStackTrace();
}
return ph.findById(id);
}
}
これはpersistence.xmlです
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="PhoneBook" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/test</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
</properties>
</persistence-unit>
</persistence>
リンク上:
http://localhost:8080/PhoneBook/persons/1
私は次のように広告出力をアスペクトします。
{"id":1,"name":"Roberto","phonenumberses":[{"number":"+01932932"......
しかし、私は次のようなサイクルを持っています:
{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":{"id":1,"name":"Roberto","phonenumberses":[{"number":"01932932","persons":