英文:
JPA join 2 Entity based upon 1 common entity
问题
package com.example.demo.model;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "country")
public class Country {
@Id
@Column(name = "countryid")
private int countryId;
@Column(name = "countryname")
private String countryName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "country")
private List<CountryRegion> regions = new ArrayList<>();
public int getCountryId() {
return countryId;
}
public void setCountryId(int countryId) {
this.countryId = countryId;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public List<CountryRegion> getRegions() {
return regions;
}
public void setRegions(List<CountryRegion> regions) {
this.regions = regions;
}
}
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "region")
public class Region {
@Id
@Column(name = "regionid")
private int regionId;
@Column(name = "regionname")
private String regionName;
@OneToMany(mappedBy = "region", fetch = FetchType.LAZY)
private List<CountryRegion> countries = new ArrayList<>();
public int getRegionId() {
return regionId;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
public String getRegionName() {
return regionName;
}
public void setRegionName(String regionName) {
this.regionName = regionName;
}
public List<CountryRegion> getCountries() {
return countries;
}
public void setCountries(List<CountryRegion> countries) {
this.countries = countries;
}
}
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "countryregion1")
public class CountryRegion implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "regionid", referencedColumnName = "regionId")
private Region region;
@Id
@ManyToOne
@JoinColumn(name = "countryid", referencedColumnName = "countryId")
private Country country;
public Region getRegion() {
return this.region;
}
public void setRegion(Region region) {
this.region = region;
}
public Country getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
}
package com.example.demo.dao;
import com.example.demo.model.Country;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CountryRepository extends CrudRepository<Country, Integer> {
@Override
List<Country> findAll();
}
package com.example.demo.dao;
import com.example.demo.model.Region;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RegionRepository extends CrudRepository<Region, Integer> {
@Override
List<Region> findAll();
}
Please note that the changes I made are as follows:
- Changed the
fetch
attribute in the@OneToMany
annotations toFetchType.LAZY
to avoid unnecessary eager loading. - Removed the
@JsonBackReference
annotation, as it's not needed in this case. - Made sure that the
CountryRegion
class has proper associations withCountry
andRegion
using the@ManyToOne
annotations. - Please ensure that your controller and service are properly implemented to expose the required API to fetch data.
This code should help you avoid the infinite loop issue while serializing to JSON.
英文:
I have 3 tables - Country, Region and CountryRegion.
- Country - countryId(PK), countryName
- Region - regionId(PK), regionName
- CountryRegion - countryId(FK), regionId(FK)
I want to fetch list of countries when I fetch region. like :
*
{
regionId:11
regionName:"abc"
countries: [
{countryId:"67",
countryName:"us"
},
{...}
]
}
*
There is no need of CountryRegion table but working with legacy DB.
I have implemented :
package com.example.demo.model;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "country")
public class Country {
@Id
@Column(name = "countryid")
private int countryId;
@Column(name = "countryname")
private String countryName;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "country")
private List<CountryRegion> regions = new ArrayList<>();
public int getCountryId() {
return countryId;
}
public void setCountryId(int countryId) {
this.countryId = countryId;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public List<CountryRegion> getRegions() {
return regions;
}
public void setRegions(List<CountryRegion> regions) {
this.regions = regions;
}
}
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "region")
public class Region {
@Id
@Column(name = "regionid")
private int regionId;
@Column(name = "regionname")
private String regionName;
@OneToMany(mappedBy = "region")
private List<CountryRegion> countries = new ArrayList<>();
public int getRegionId() {
return regionId;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
public String getRegionName() {
return regionName;
}
public void setRegionName(String regionName) {
this.regionName = regionName;
}
public List<CountryRegion> getCountries() {
return countries;
}
public void setCountries(List<CountryRegion> countries) {
this.countries = countries;
}
}
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name = "countryregion1")
public class CountryRegion implements Serializable {
@Id @ManyToOne
@JoinColumn(name = "regionid", referencedColumnName = "regionId")
private Region region;
@Id @ManyToOne
@JoinColumn(name = "countryid", referencedColumnName = "countryId")
private Country country;
public Region getRegion() {
return this.region;
}
public void setRegion(Region region) {
this.region = null;
}
public Country getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
}
package com.example.demo.dao;
import com.example.demo.model.Country;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CountryRepository extends CrudRepository<Country, Integer> {
@Override
List<Country> findAll();
}
package com.example.demo.dao;
import com.example.demo.model.Country;
import com.example.demo.model.Region;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface RegionRepository extends CrudRepository<Region, Integer> {
@Override
List<Region> findAll();
}
- Controller and service to expose api to get data.
There is something wrong in code above as I only want to fetch list of countries(or Region in case country)
This code is causing a infinite loop in JSON. Tried Json Ignore etc. but in that case i am not getting any value in lists.
TIA !!
答案1
得分: 0
首先,您应该指定"Country"和"Region"之间的关系。我认为您不需要定义"CountryRegion"类。如果关系是多对多的,您可以在"Region"类中使用以下代码:
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "Employee_Project",
joinColumns = { @JoinColumn(name = "regionid") },
inverseJoinColumns = { @JoinColumn(name = "countryid") }
)
Set<Country> countries = new HashSet<>();
如果是一对多的关系,您在"Region"类中实现的关系就足够了。但我认为您希望实现与您的愿望相对应的多对多关系。
英文:
first of all you should specify the relation between Country and Region. I think you dont need to define CountryRegion class.if the relation is ManyToMany then you can use below code in Region class :
@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(
name = "Employee_Project",
joinColumns = { @JoinColumn(name = "regionid") },
inverseJoinColumns = { @JoinColumn(name = "countryid") }
)
Set<Country > countries = new HashSet<>();
and if it is OneToMany the raltion that you implement in Region class is enough. but i think you want ManyToMany corresponding to your wish
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论