У меня есть две сущности Country
и State
@Getter @Setter //@EqualsAndHashCode(doNotUseGetters=true)
@Entity
@Table(name = "country", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }) })
public class Country {
@Id
@Column(name = "country_id")
private int countryId;
@Column(name = "name", length = 45)
private String name;
@Column(name = "phonecode", length = 45)
private int phoneCode;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "country")
private Set<State> states;
}
@Getter @Setter // @EqualsAndHashCode(doNotUseGetters=true)
@Entity
@Table(name = "state")
public class State {
@Id
@Column(name = "state_id")
private int stateId;
@Column(name = "name", length = 45)
@NotBlank
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "country_id", nullable = false)
private Country country;
}
Я использую Spring-boot, поэтому я написал тест, чтобы получить города страны
@Autowired
private CountryDao countryDao;
@Test
@Transactional
public void getAllStateWithCountryName() {
Country country = countryDao.findById(101).orElseThrow(() -> new EntityNotFoundException());
System.out.println("country: " + country.getName());
country.getStates().forEach((state) -> {
System.out.println("state: " + state.getName());
});
}
В тот момент, когда я раскомментирую @EqualsAndHashCode(doNotUseGetters=true)
, отображение ведет себя EAGER
и даже переходит к StackOverFlowError
.Ранее я догадывался, что где-то в equals()
или hashcode()
вызывается getStates()
(выглядит как загрузка EAGER
), но так как я использовал флаг doNotUseGetters=true
, который убедил меня, что геттер не находится впроблема.Затем я посмотрел на сгенерированный код lambok
, и виновником был не получатель, а использование коллекции cities
внутри реализации hashcode()
.
Сгенерированный hashCode()
public int hashCode()
{
int PRIME = 59;
int result = 1;
result = result * 59 + this.stateId;
Object $name = this.name;
result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $cities = this.cities;
result = result * 59 + ($cities == null ? 43 : $cities.hashCode()); //problem here
return result;
}
Проблема заключается в $cities.hashCode()
.Если я закомментирую это использование $cities
, все будет нормально.
Итак, я должен реализовать свою собственную (не используя Lombok
) реализацию hashCode()
, сохраняя cities
?Это будет правильная реализация?
Журналы:
Hibernate: select country0_.country_id as country_1_12_0_, country0_.name as name2_12_0_, country0_.phonecode as phonecod3_12_0_ from country country0_ where country0_.country_id=?
country: India
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
Hibernate: select states0_.country_id as country_3_38_0_, states0_.state_id as state_id1_38_0_, states0_.state_id as state_id1_38_1_, states0_.country_id as country_3_38_1_, states0_.name as name2_38_1_ from state states0_ where states0_.country_id=?
......................until stackoverlow error