gpt4 book ai didi

java - Spring MVC JPA @ManyToMany 双向

转载 作者:行者123 更新时间:2023-11-30 06:59:34 26 4
gpt4 key购买 nike

希望一切顺利。

我正在尝试使用 Spring Boot、Spring Data JPA、Hibernate、Gradle 和 Spring Data Rest 在 Spring MVC 中实现 @ManyToMany 双向映射。当我实现两 (2) 个实体、事件和标签之间的映射时。一个事件可以有零到多个标签,一个标签可以与零到多个事件相关联。事实上,我能够通过映射实体的 setter 将 POJO 成功保存到 hibernate session ,包括 HashSet<>() 。但是,一旦我尝试通过 CrudRepository 方法(例如 .findAll())查询 POJO 列表,它就会立即崩溃。查看控制台输出,Hibernate 似乎试图附加另一个对象一百多次。由于我将 @RestController 用于列表操作 (.findAll()),当我导航 RESTful 端点时,它不仅显示两个 JSON 对象,还显示大量未闭合的附加困惑JSON 片段。控制台输出还表明 jackson databind 可能在序列化 Hibernate 输出的 .findAll() 结果时遇到问题。

如有任何帮助,我们将不胜感激。对我来说最大的困惑是为什么 Hibernate 会多次尝试附加结果字符串。这可能是以下方面的问题:

  1. @ManyToMany 映射配置?需要在 Tag 实体上使用 @JoinColumns?
  2. fetch = FetchType.EAGER?
  3. 缺少/过多的 GETTER/SETTER?从事件或标签实体中删除/添加 GETTER/SETTER?
  4. Spring Boot 和/或 Gradle?我可以在互联网上找到的任何其他示例都是使用 Maven。
  5. 依赖项? spring-starter-boot-starter-data-jpa vs spring-data-jpa?
  6. 构造函数? (Event.java 没有标签的参数构造函数)
  7. 事件和/或标签的 HashSet<>() 属性类型?

build.gradle

dependencies {
compile("org.springframework.boot:spring-boot-starter-data-rest")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.hibernate:hibernate-validator")
compile("org.apache.tomcat.embed:tomcat-embed-el")
compile("com.h2database:h2")
}

Event.java

package event.model;

import org.hibernate.validator.constraints.Email;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.*;

@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"title", "date"})})
public class Event {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@NotNull
@Size(min = 2, max = 55)
private String title;

// .. some additional private variables

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "events_tags",
joinColumns=@JoinColumn(name = "event_id"),
inverseJoinColumns = @JoinColumn(name="tag_id")
)
private Set<Tag> tags = new HashSet<>();

public Event() {
}

public Event(String title, String description, Date date, String organizer, String email, String location) {
this.title = title;
this.description = description;
this.date = date;
this.organizer = organizer;
this.email = email;
this.location = location;
}

public long getId() {
return id;
}

// .. GETTERS and SETTERS for other properties

public Set<Tag> getTags(){
return tags;
}

public void setTags(Set<Tag> tags){
this.tags = tags;
}

// @Overide toString() method
}

Tag.java

package event.model;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.*;

@Entity
public class Tag {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@NotNull
@Size(min = 3, max = 255)
private String title;

@ManyToMany(mappedBy = "tags", fetch = FetchType.EAGER)
private Set<Event> events = new HashSet<>();

public Tag() {
}

public Tag(String title) {
this.title = title;
}

public long getId() {
return id;
}

// .. GETTERS AND SETTERS

public Set<Event> getEvents() {
return events;
}

public void setEvents(Set<Event> events){
this.events = events;
}

// @Override toString() method

Application.java

@SpringBootApplication
public class Application implements CommandLineRunner {

@Autowired
EventRepository eventRepository;

@Autowired
TagRepository tagRepository;

public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}

@Override
public void run(String... strings) throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyyy HH:mm a");
String[] dateStrings = {"07-25-2015 12:00 PM", "08-25-2015 12:00 PM"};

Date date1 = formatter.parse(dateStrings[0]);
Date date2 = formatter.parse(dateStrings[1]);

Event event1 = eventRepository.save(new Event("Bacon Day", "This day is about bacon. I just need so much bacon all the time", date1, "John Smith", "john.smith@test.com", "W523"));
Event event2 = eventRepository.save(new Event("Salad Day", "This day is about salad. I just need so much salad all the time", date2, "Jane Smith", "jane.smith@test.com", "N423"));

Tag tag1 = tagRepository.save(new Tag("Savory"));
Tag tag2 = tagRepository.save(new Tag("Vegetarian"));

event1.getTags().add(tag1);
event1.getTags().add(tag2);
event1 = eventRepository.save(event1);
System.out.println(event1);
System.out.println(eventRepository.findAll());
}
}

控制台错误输出

Hibernate: select events0_.tag_id as tag_id2_2_0_, events0_.event_id as event_id1_1_0_, event1_.id as id1_0_1_, event1_.date as date2_0_1_, event1_.description as descript3_0_1_, event1_.email as email4_0_1_, event1_.location as location5_0_1_, event1_.organizer as organize6_0_1_, event1_.title as title7_0_1_ from events_tags events0_ inner join event event1_ on events0_.event_id=event1_.id where events0_.tag_id=?
2015-07-13 18:35:28.084 ERROR 4088 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.StackOverflowError] with root cause

java.lang.StackOverflowError: null
at java.util.Date.getYear(Date.java:651)
at java.sql.Timestamp.toString(Timestamp.java:279)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at event.model.Event.toString(Event.java:128)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:317)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at event.model.Tag.toString(Tag.java:51)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:317)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at event.model.Event.toString(Event.java:128)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:317)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at event.model.Tag.toString(Tag.java:51)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:317)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)

这会持续数百行。

最佳答案

尝试在父集合的子类中使用 @JsonIgnore。它正在尝试递归序列化。

Follow此链接用于处理此问题的其他方法。

关于java - Spring MVC JPA @ManyToMany 双向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31395352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com