2017-10-04 1 views
0

Je suis nouveau avec l'utilisation de spring boot + jersey api + JPA. J'ai hava trois entité qui utilise un à plusieurs mappage bidirectionnel. Quand j'ai utilisé spring boot + jersey api + JPA j'ai une erreur: failed to lazily initialize a collection of role: com.kavinaam.GSTbilling.entity.Country.states, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.kavinaam.GSTbilling.entity.City["states"]->com.kavinaam.GSTbilling.entity.States["countyId"]->com.kavinaam.GSTbilling.entity.Country["states"])Spring boot + jersey api + JPA: manqué d'initialiser paresseusement une collection de rôle

J'ai ajouté mon entité, dao, services et point final.

@Entity 
@Table(name="country") 
public class Country implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id") 
    private int id; 
    @Column(name="countryName") 
    private String countryName; 

    @OneToMany(mappedBy = "countyId",cascade = CascadeType.ALL) 
    private Set<States> states; 

    public int getId() { 
     return id; 
    } 

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

    public String getCountryName() { 
     return countryName; 
    } 

    public void setCountryName(String countryName) { 
     this.countryName = countryName; 
    } 

    public Set<States> getStates() { 
     return states; 
    } 

    public void setStates(Set<States> states) { 
     this.states = states; 
    } 

} 

Ma classe d'état:

@Entity 
@Table(name="states") 
public class States implements Serializable { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
@Column(name="id") 
private int id; 

@ManyToOne 
@JoinColumn(name="countyId") 
private Country countyId; 

@Column(name="stateName") 
private String stateName; 

@OneToMany(mappedBy = "states", cascade = CascadeType.ALL) 
private Set<City> city; 

public int getId() { 
    return id; 
} 
public void setId(int id) { 
    this.id = id; 
} 


public Country getCountyId() { 
    return countyId; 
} 
public void setCountyId(Country countyId) { 
    this.countyId = countyId; 
} 
public String getStateName() { 
    return stateName; 
} 
public void setStateName(String stateName) { 
    this.stateName = stateName; 
} 
public Set<City> getCity() { 
    return city; 
} 
public void setCity(Set<City> city) { 
    this.city = city; 
} 
} 

Ma classe ville:

@Entity 
@Table(name="cities") 
public class City implements Serializable{ 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
@Column(name="id") 
private int id; 

@ManyToOne 
@JoinColumn(name="stateId") 
private States states; 

@Column(name="cityName") 
private String cityName; 

@Column(name="zip") 
private String zip; 


public void setId(int id) { 
    this.id = id; 
} 
public void setZip(String zip) { 
    this.zip = zip; 
} 


public States getStates() { 
    return states; 
} 
public void setStates(States states) { 
    this.states = states; 
} 
public String getCityName() { 
    return cityName; 
} 
public void setCityName(String cityName) { 
    this.cityName = cityName; 
} 
public String getZip() { 
    return zip; 
} 
public int getId() { 
    return id; 
} 

} 

Mon OAC:

@Transactional 
@Repository 
public class GSTCityDAO implements IGSTCityDAO { 

@PersistenceContext 
private EntityManager entityManager; 

//@SuppressWarnings("unchecked") 
@Override 
public List<City> getAllCities() { 
    //Session session = sessionFactory.getCurrentSession(); 
    String hql = "FROM City as ct ORDER BY ct.id"; 
    List<City> l = entityManager.createQuery(hql,City.class).getResultList(); 

    return l; 
    } 

@Override 
public City getCityById(int cityId) { 
    return entityManager.find(City.class, cityId); 
} 

@SuppressWarnings("unchecked") 
@Override 
public List<City> getCityByStateId(States stateId) { 
    String getcitybystate = " FROM City as c WHERE c.states = ?"; 
    return (List<City>) entityManager.createQuery(getcitybystate).setParameter(1, stateId).getResultList(); 
} 

@Override 
public void addCity(City city) { 
    entityManager.persist(city); 

} 

@Override 
public void updateCity(City city) { 
    City cityctl = getCityById(city.getId()); 
    cityctl.setCityName(city.getCityName()); 
    cityctl.setZip(city.getZip()); 
    cityctl.setStates(city.getStates()); 
    entityManager.flush(); 
} 

@Override 
public void deleteCity(int cityId) { 
    entityManager.remove(getCityById(cityId)); 
} 

@Override 
public boolean cityExists(String name, String zip) { 
    String hql = "FROM City WHERE cityName = ? and zip = ?"; 
    int count = entityManager.createQuery(hql).setParameter(1,name).setParameter(2, zip).getResultList().size(); 
    return count > 0 ? true : false; 
} 

} 

Services:

@Service 
public class GSTCityService implements IGSTCityService { 

@Autowired 
private IGSTCityDAO cityDAO; 

@Override 
public List<City> getAllCities() { 
    List<City> l = cityDAO.getAllCities(); 
    Hibernate.initialize(l); 
    return l; 
} 

public List<City> getCityByStateId(States stateId) { 
     return cityDAO.getCityByStateId(stateId); 
} 

@Override 
public City getCityById(int cityId) { 
    City city = cityDAO.getCityById(cityId); 
    return city; 
} 

@Override 
public synchronized boolean addCity(City city) { 
    if(cityDAO.cityExists(city.getCityName(), city.getZip())){ 
     return false; 
    }else{ 
     cityDAO.addCity(city); 
    return true; 
    } 
} 

@Override 
public void updateCity(City city) { 
    cityDAO.updateCity(city); 
} 

@Override 
public void deleteCity(int cityId) { 
    cityDAO.deleteCity(cityId); 

} 

} 

End Point:

@Component 
@Path("/") 
public class Test { 
private static final Logger logger = LoggerFactory.getLogger(Test.class); 
@Autowired 
private IGSTCityService cityService; 

@GET 
@Path("/hi") 
@Produces(MediaType.APPLICATION_JSON) 
public Response hello(){ 
    return Response.ok("Hello GST").build(); 
} 

@GET 
@Path("/test") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getAllDate(){ 
    List<City> list = cityService.getAllCities(); 
    for(City city: list){ 
     System.out.println(city); 
    } 
    return Response.ok(list).build(); 
} 

@GET 
@Path("/test/{id}") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getAllDateBySome(@PathParam("id") Integer id){ 
    States state = new States(); 
    state.setId(id); 
    List<City> list = cityService.getCityByStateId(state); 
    return Response.ok(list).build(); 
} 

@GET 
@Path("/{id}") 
@Produces(MediaType.APPLICATION_JSON) 
public Response getDataById(@PathParam("id")Integer id){ 
    City citl = cityService.getCityById(id); 
    return Response.ok(citl).build(); 
} 

@POST 
@Path("/add") 
@Consumes(MediaType.APPLICATION_JSON) 
public Response addData(City city){ 
    boolean isAdded = cityService.addCity(city); 
    if(!isAdded){ 
     return Response.status(Status.CONFLICT).build(); 
    } 
    return Response.created(URI.create("/gst/"+ city.getId())).build(); 
} 

@PUT 
@Path("/update") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public Response updateCountry(City city){ 
     cityService.updateCity(city); 
     return Response.ok(city).build(); 
} 

@DELETE 
@Path("/{id}") 
@Consumes(MediaType.APPLICATION_JSON) 
public Response deleteCountry(@PathParam("id")Integer id){ 
    cityService.deleteCity(id); 
    return Response.noContent().build(); 
} 

} 

J'utilise l'importation org.springframework.transaction.annotation.Transactional; pour transnational dans DAO. Je ne peux pas utiliser @PersistenceContext (type = PersistenceContextType.EXTENDED) chercher le type Désireuse parce que j'obtiens l'erreur de taille maximale de la pile a dépassé

+0

l'erreur se produit lors de l'appel de quelles méthodes? –

+0

public Réponse getAllDate() { \t \t Liste liste = cityService.getAllCities(); \t \t pour (Ville: liste) { \t \t \t System.out.println (city); \t \t} \t \t return Response.ok (liste) .build(); \t \t} Une erreur se produit lors du renvoi de Response.ok (liste) .build(). Ce que je pense est quand il demande une réponse à imprimer des données dans le navigateur, la session peut être fermée. –

Répondre

0

Vous devriez faire un ou les deux des éléments suivants:

1 Déplacer le @Transactional de DAO au service. C'est une bonne idée en général, comme d'habitude sont toujours en train de traiter les entités de résultat d'une manière ou d'une autre sur cette couche.

2) Fetch les dépendances dans les requêtes explicitement:

select ct FROM City as ct inner join fetch ct.states s ORDER BY ct.id 
+0

n'a pas pu paresseusement initialiser une collection de rôle: com.kavinaam.GSTbilling.entity.Country.états, n'a pas pu initialiser proxy - aucune session (via la chaîne de référence: java.util.ArrayList [0] -> com.kavinaam.GSTbilling.entity.City ["states"] -> com.kavinaam.GSTbilling.entity.States [ "countyId"] -> com.kavinaam.GSTbilling.entity.Country ["states"]) toujours la même erreur –

+0

donc ajoutez jointure interne fetch s.country c –

+0

même. pas de changement dans l'erreur. –

0

Je l'ai résolu en utilisant le @JsonBackReference sur les relations OneToMany. Le problème est avec la sérialisation et la désérialisation. "la propriété annotée avec l'annotation @JsonManagedReference est gérée normalement (sérialisée normalement, aucune manipulation spéciale pour la désérialisation) et la propriété annotée avec l'annotation @JsonBackReference n'est pas sérialisée, et sa valeur est définie sur l'instance qui a le" managed " (transférer). "