У меня есть 2 объекта: Человек< /strong> и Адрес, и я пытаюсь установить двунаправленную связь OneToMany/ManyToOne .
Я использую Spring Data JPA, который внутреннее использование Hibernate Core 6.6.4, Java 17 и SpringBoot 3.4.1 и MySQL.
Создание таблиц: -
Код: Выделить всё
create table if not exists `person` (
`person_id` int AUTO_INCREMENT primary key ,
`name` varchar(20) not null ,
`age` int not null ,
`contact_id` int not null ,
`created_at` TIMESTAMP not null,
`created_by` varchar(10) not null,
`updated_at` TIMESTAMP default null,
`updated_by` varchar(10) default null ,
foreign key (contact_id) references contact(contact_id)
) ;
create table if not exists `address` (
`addressId` int AUTO_INCREMENT primary key ,
`city` varchar(20) not null ,
`state` varchar(20) not null ,
`country` varchar(20) not null ,
`person_id` int not null ,
`created_at` TIMESTAMP not null,
`created_by` varchar(10) not null,
`updated_at` TIMESTAMP default null,
`updated_by` varchar(10) default null ,
foreign key (person_id) references person(person_id)
) ;
Код: Выделить всё
package com.anshu.example.model;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.HashSet;
import java.util.Set;
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@Table(name = "person")
public class Person extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "person_id")
private int personId ;
private String name ;
private int age ;
@OneToOne(fetch = FetchType.EAGER , cascade = CascadeType.ALL , targetEntity = Contact.class)
@JoinColumn(name = "contact_id" , referencedColumnName = "contact_id" , nullable = false)
private Contact contact ;
@OneToMany(mappedBy = "person" , cascade = CascadeType.ALL , fetch = FetchType.LAZY , targetEntity = Address.class)
private Set addresses = new HashSet();
}
Код: Выделить всё
package com.anshu.example.model;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table
@Data
public class Address extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int addressId ;
private String city ;
private String state ;
private String country ;
@ManyToOne(optional = false)
@JoinColumn(name = "person_id" , referencedColumnName = "person_id")
private Person person ;
}
Код: Выделить всё
package com.anshu.example.model;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Data;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
@Column(name = "created_at" , updatable = false)
@CreatedDate
private LocalDateTime createdAt ;
@Column(name = "created_by" , updatable = false)
@CreatedBy
private String createdBy ;
@LastModifiedDate
@Column(name = "updated_at" )
private LocalDateTime updatedAt ;
@Column(name = "updated_by" )
@LastModifiedBy
private String updatedBy ;
}
Код: Выделить всё
package com.anshu.example.service;
import com.anshu.example.model.Person;
import com.anshu.example.repo.PersonRepo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class PersonService {
private final PersonRepo personRepo ;
public PersonService(PersonRepo personRepo) {
this.personRepo = personRepo ;
}
public Person save(Person person) {
log.info(person.toString());
return personRepo.save(person) ;
}
}
Код: Выделить всё
{
"name": "Anshu Anand",
"age": 25,
"contact": {
"name": "Anshu",
"email": "[email protected]",
"message": "Home Contact",
"status": "OPEN"
},
"addresses":[
{
"city":"B",
"state":"A",
"country":"C"
},
{
"city":"V",
"state":"A",
"country":"C"
}
]}
[img]https://i .sstatic.net/x80VxkiI.png[/img]
РЕДАКТИРОВАТЬ: -
Согласно комментарию @Turo, Я попробовал внести изменения в свой класс обслуживания ниже, это привело к StackOverflowError
Код: Выделить всё
@Slf4j
@Service
public class PersonService {
private final PersonRepo personRepo ;
public PersonService(PersonRepo personRepo) {
this.personRepo = personRepo ;
}
public Person save(Person person) {
log.info(person.toString());
for(Address address : person.getAddresses()) {
address.setPerson(person);
}
return personRepo.save(person) ;
}
}
Код: Выделить всё
java.lang.StackOverflowError: null
at com.anshu.example.model.BaseEntity.hashCode(BaseEntity.java:15) ~[classes/:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
at com.anshu.example.model.Address.hashCode(Address.java:7) ~[classes/:na]
at java.base/java.util.AbstractSet.hashCode(AbstractSet.java:124) ~[na:na]
at com.anshu.example.model.Person.hashCode(Person.java:10) ~[classes/:na]
....
После следующих предложений Джона, хотя я и могу сохранять объекты в таблице, но столкнулся со следующей проблемой.< /strong>
Может кто-нибудь объяснить, что происходит после сохранения объектов и как JPA формирует объект, который возвращается в ответе «save()»?
Код: Выделить всё
2025-01-09T23:16:42.178+05:30 WARN 5900 --- [example] [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from `StreamWriteConstraints.getMaxNestingDepth()`)
2025-01-09T23:16:42.178+05:30 WARN 5900 --- [example] [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Document nesting depth (1001) exceeds the maximum allowed (1000, from `StreamWriteConstraints.getMaxNestingDepth()`)]
Подробнее здесь: https://stackoverflow.com/questions/793 ... lways-null