2013-07-03 13 views
11

To moje pierwsze pytanie tutaj na stosie, więc proszę o łagodny: DHibernate OneToMany java.lang.StackOverflowError

Próbuję utworzyć hibernacji OneToMany związek. Kiedy próbuję pobrać niektóre dane z mojego DB, otrzymuję komunikat StackOverflowError. Ale kiedy usuwam część OneToMany, wszystko idzie normalnie. Jest to część mojej usługi REST, na razie działa na VMware vFabric Server i MySQL DB.

Fetch przykład:

@Inject 
private EntityManager entityManager; 
... 
entityManager.find(League.class, 1); 
... 
entityManager.find(Team.class, 1); 

skrypt MySQL:

CREATE TABLE league (
    id int(11) NOT NULL AUTO_INCREMENT, 
    name varchar(20) COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE team (
    team_id int(11) NOT NULL AUTO_INCREMENT, 
    name varchar(20) COLLATE utf8_unicode_ci NOT NULL, 
    fk_leagueId int(11) NOT NULL, 
    PRIMARY KEY (team_id), 
    FOREIGN KEY (fk_leagueId) REFERENCES league(id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Ćwiczenia:

@XmlRootElement 
@Entity 
@Table(name = "team") 
@Data 
public class Team { 
    @Id 
    @GeneratedValue(generator = "increment") 
    @GenericGenerator(name = "increment", strategy = "increment") 
    @Column(name = "team_id") 
    private int id; 
    @Column(name = "name") 
    private String name; 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "fk_leagueId", nullable = false) 
    private League league; 
} 

@XmlRootElement 
@Entity 
@Table(name = "league") 
@Data 
public class League { 
    @Id 
    @GeneratedValue(generator = "increment") 
    @GenericGenerator(name = "increment", strategy = "increment") 
    @Column(name = "id") 
    private int id; 
    @Column(name = "name") 
    private String name; 
    //if I comment 2 lines below, there is no error, and everything works fine 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "league") 
    private Set<span><</span>Team> teams; 
} 

Błąd:

Hibernate: select league0_.id as id1_1_0_, league0_.name as name2_1_0_ from league league0_ where league0_.id=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=? 
Exception in thread "tomcat-http--3" java.lang.StackOverflowError 
    at org.jboss.logging.JDKLogger.translate(JDKLogger.java:73) 
    at org.jboss.logging.JDKLogger.isEnabled(JDKLogger.java:85) 
    at org.jboss.logging.JDKLogger.doLog(JDKLogger.java:41) 
    at org.jboss.logging.Logger.debug(Logger.java:406) 
    at org.hibernate.internal.CoreMessageLogger_$logger.debug(CoreMessageLogger_$logger.java:525) 
    at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104) 
    at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:95) 
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:180) 
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:159) 
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1858) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1835) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1815) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:899) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:311) 
    at org.hibernate.loader.Loader.loadCollection(Loader.java:2234) 
    at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:65) 
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:674) 
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83) 
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1849) 
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:549) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:234) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124) 
    at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:428) 
    at com.lukaszb.motspe.webapp.model.League.hashCode(League.java:21) 
    at com.lukaszb.motspe.webapp.model.Team.hashCode(Team.java:20) 
    at java.util.HashMap.hash(HashMap.java:351) 
    at java.util.HashMap.put(HashMap.java:471) 
    at java.util.HashSet.add(HashSet.java:217) 
... 

Edit:

udało mi się rozwiązać ten problem się dzięki @Thihara i @KarIP. Przesunąłem toString() dla zespołu i ligi tak:

@Override 
public String toString() { 
    return "League [id=" + id + ", name=" + name + "]"; 
} 

@Override 
public String toString() { 
    return "Team [id=" + id + ", name=" + name + "]"; 
} 

i udało mi się pobrać dane z DB zgodnie z oczekiwaniami. Ale podczas analizowania otrzymałem błąd JAXB z nieskończonymi cyklami. Zanotowałem więc klasę drużynową i ligową z @XmlAccessorType(XmlAccessType.FIELD), więc nie przyjrzymy się metodom i polu zespołu jako @XmlTransient, więc nie będzie on analizowany.

Tutaj mogę nawet usunąć moje implementacje toString() i nadal działa. Nie jestem do końca pewien, dlaczego. Problem został rozwiązany, ale chciałbym usłyszeć dokładniejsze wyjaśnienie. Nie wiem, dlaczego JAXB zatrzymał pobieranie danych, nawet jeśli jest to po całym procesie komunikacji DB (lub nie jest?). Aby być bardziej konkretne, używam do tego Jersey:

@GET 
@Path("search/id") 
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) 
public List<League> searchById(@QueryParam("id") int id) { 
return Arrays.asList(leagueDAO.getById(id)); 
} 
+0

w swojej klasie ligi masz definiują zestaw zespołu, ale umieścić jeden do wielu adnotacji abouce jego getter i setter –

+0

Jest to dobre pytanie, tak upvote dla Ciebie. \ – Siddharth

Odpowiedz

15

Jedynym sposobem może rzucać StackOverflow jest, gdy twoja drużyna League jest dostępny rekurencyjnie ....

drużyny do Ligi zespołu do League

Zgaduję, że istnieje pewna funkcja, która próbuje przekształcić twoje obiekty w inną reprezentację odbijającą lub rekursywnie, co skutkuje nieskończoną pętlą.

+11

Tak, toString() jest zwykle podejrzany ... – KarlP

+0

Dzięki, to dało mi rozwiązanie. – otocon

+4

Dzięki za radę! Dla mnie był to _hashCode_ w klasie "wiele do wielu" – SaganTheBest

10

Miałem bardzo podobny problem. Użyłem adnotacji Lombok na @Data w moich obiektach modelu, aby automatycznie generować metody pobierające, ustawiające i inne standardowe metody. Wierzę, że metoda toString() wygenerowana przez Lombok wprowadziła okrągłą zależność między moimi obiektami Team i League. Kiedy próbowałem uzyskać Set<teams> teams z mojego obiektu League, otrzymałem java.lang.StackOverflowError, ponieważ Spring wywoływał metodę toString dla celów logowania (chyba).

Rozwiązałem to, rozwiązując metodę Lombok'a: toString(). Zastąpiłem adnotację @Data adnotacjami Lombok: @Getter i @Setter. W ten sposób nadal mogłem korzystać z darmowych programów pobierających i ustawiających bez uzyskania metody toString().

+0

Dzięki, pomogło to. Ewentualnie możesz nadal używać adnotacji '@ Data', ale dodaj adnotację' @ ToString' i określ wykluczoną właściwość, taką jak: @ToString (exclude = {"propName"}). –

Powiązane problemy