2013-07-03 37 views
11

Đây là câu hỏi đầu tiên của tôi ở đây trên ngăn xếp, vì vậy hãy nhẹ nhàng: DHibernate OneToMany java.lang.StackOverflowError

Tôi đang cố tạo mối quan hệ OneToMany ngủ đông. Khi tôi cố gắng lấy một số dữ liệu từ DB của tôi, tôi nhận được StackOverflowError. Nhưng khi tôi xóa phần OneToMany, mọi thứ diễn ra bình thường. Đây là một phần của dịch vụ REST của tôi, bây giờ nó chạy trên VMware vFabric Server và MySQL DB.

Fetch dụ:

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

MySQL kịch bản:

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; 

Lớp học:

@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; 
} 

Lỗi:

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:

tôi đã có thể giải quyết việc này ra nhờ @Thihara và @KarIP. Tôi đã overriden toString() cho Team và League như sau:

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

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

và có thể tìm nạp dữ liệu từ DB như mong muốn. Nhưng sau đó trong khi phân tích cú pháp tôi đã nhận lỗi JAXB với chu kỳ vô hạn. Vì vậy, tôi đã chú thích nhóm Team và League với @XmlAccessorType(XmlAccessType.FIELD), vì vậy nó sẽ không xem xét các phương pháp và trường Team là @XmlTransient, vì vậy nó sẽ không được phân tích cú pháp.

Ở đây tôi thậm chí có thể xóa các cài đặt toString() của mình và nó vẫn hoạt động. Tôi không hoàn toàn chắc chắn tại sao. Vấn đề được giải quyết, nhưng tôi muốn nghe giải thích chính xác hơn. Tôi không biết tại sao JAXB dừng tìm nạp dữ liệu, ngay cả khi nó sau quá trình truyền thông DB toàn bộ (hay không?). Để cụ thể hơn, tôi đang sử dụng Jersey cho rằng:

@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

trong lớp học giải đấu của bạn, bạn đã xác định nhóm nhưng đặt một đến nhiều chú thích abouce getter và setter của nó –

+0

Đó là một câu hỏi hay, do đó, upvote cho bạn. \ – Siddharth

Trả lời

15

Cách duy nhất nó có thể ném một Stackoverflow là khi League Đội của bạn được truy cập một cách đệ quy ....

đội để giải về Team đến League

Tôi đoán có một số chức năng cố gắng chuyển đổi các đối tượng của bạn thành một số biểu diễn khác một cách phản xạ hoặc đệ quy dẫn đến một vòng lặp vô hạn.

+11

Có, toString() thường là một nghi ngờ ... – KarlP

+0

Cảm ơn, điều đó đã cho tôi một giải pháp. – otocon

+4

Cảm ơn lời khuyên! Đối với tôi, nó là _hashCode_ trong một lớp học nhiều-nhiều-nhiều, – SaganTheBest

10

Tôi gặp sự cố tương tự. Tôi đã sử dụng chú thích @Data của Lombok trên các đối tượng mô hình của tôi để tự động tạo các getters, setters và các phương thức chuẩn khác. Tôi tin rằng phương pháp toString() do Lombok tạo ra đã giới thiệu một sự phụ thuộc vòng tròn giữa các đối tượng TeamLeague của tôi. Khi tôi cố gắng để có được Set<teams> teams từ đối tượng League của tôi, tôi nhận được java.lang.StackOverflowError vì Spring đang gọi phương thức toString cho mục đích ghi nhật ký (tôi nghĩ).

Tôi giải quyết được giải pháp này bằng cách loại bỏ phương pháp toString() của Lombok. Tôi đã thay thế chú thích @Data bằng các chú thích @Getter@Setter của Lombok. Bằng cách đó tôi vẫn có thể hưởng lợi từ getters miễn phí và setters mà không nhận được phương pháp toString().

+0

Cảm ơn, điều này đã giúp. Ngoài ra, bạn vẫn có thể sử dụng chú thích '@ Data', nhưng thêm chú thích' @ ToString' và chỉ định một thuộc tính bị loại trừ như: '@ToString (exclude = {" propName "})' –

Các vấn đề liên quan