打印出ManyToMany实体时出现异常



我正在使用Spring Data JPA创建一个简单的项目来学习。

我有这个实体(为了清晰起见,删除了getter/setter(:

@Entity
@Table(name = "shop")
@JsonIgnoreProperties({"barbers"})
public class Shop {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idshop")
private int shopID;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
//THIS SHOWS HOW MANY BARBERS WORKS IN THIS SHOP - CHILD
@ManyToMany(mappedBy = "shops", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Barber> barbers = new LinkedHashSet<>();
public Set<Barber> getBarbers(){
return barbers;
}
public void removeBarber(Barber barber)
{
barbers.remove(barber);
barber.getShops().remove(this);
}
public void addBarber(Barber barber)
{
barbers.add(barber);
barber.getShops().add(this);
}
public Shop() {
}
public Shop(String name, String address) {
this.name = name;
this.address = address;
} this.address = address;
}
@Override
public String toString()
{
return "Shop{" +
"id=" + shopID +
", name='" + name + ''' +
", address='" + address + ''' +
", barbers='" + barbers + ''' +
'}';
}
}

我有一个简单的控制器,它可以很好地从存储库中获取请求的商店并返回。当我执行System.out.println((时,我可以看到以下内容:Shop{id=3, name='fade', address='hammersmith', barbers='[Barber{id=1, name='bob', rating='4'}]'}

但是当控制器返回对象时,我得到以下异常:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.gogobarber.barber.entities.Shop$HibernateProxy$U83qWd1X["hibernateLazyInitializer"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:46) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:29) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.0.jar:2.13.0]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.13.0.jar:2.13.0]

我有一个很好的想法,这个错误源于将pojo编组为json字符串,并且错误的原因很可能是来自Set<Barber>(尽管这个错误说找不到byteBuddy的序列化程序…这是什么?(。通常总是配置jackson对象映射器吗?我想杰克逊应该有足够的水平去应付一盘?也许是因为我配置ManyToMany关系的方式?

EDIT=这是我的控制器和Barber类:

@Entity
@Table(name = "barber")
@JsonIgnoreProperties({"shops"})
public class Barber {
public Barber() {
}
public Barber(String name, String rating) {
this.name = name;
this.rating = rating;
}
public int getBarberId() {
return barberId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public Set<Shop> getShops() {
return shops;
}
//THIS FETCHES THE SHOPS THE BARBER IS ASSOCAITED TO - PARENT
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "barberworkinshops",
joinColumns = @JoinColumn(name = "Barber_ID", referencedColumnName = "idbarber"),
inverseJoinColumns = @JoinColumn(name = "Shop_ID", referencedColumnName = "idshop")
)
private Set<Shop> shops = new LinkedHashSet<>();;
public void addBarberToShop(Shop shop)
{
shops.add(shop);
shop.getBarbers().add(this);
}
public void removeBarberFromShop(Shop shop)
{
shops.remove(shop);
shop.getBarbers().remove(this);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idbarber")
private int barberId;
@Column(name = "Name")
private String name;
@Column(name = "Rating")
private String rating;
@Override
public String toString()
{
return "Barber{" +
"id=" + barberId +
", name='" + name + ''' +
", rating='" + rating + ''' +
", shops='" + shops + ''' +
'}';
}
}

控制器:

@RestController
public class ShopController {
@Autowired
private BarberRepo barberRepo;
@Autowired
private ShopRepo shopRepo;

@GetMapping("/shop/{id}")
public Shop getShop(@PathVariable String id)
{
Shop shop = shopRepo.getById(Integer.valueOf(id));
System.out.println(shop);
return shop;
}
@PostMapping("/shop/{name}/{address}")
public Shop createShop(@PathVariable String name, @PathVariable String address)
{
Shop shop = new Shop(name, address);
return shopRepo.save(shop);
}
@PatchMapping("/shop/{sId}/addBarber/{bId}")
public Shop addBarber(@PathVariable String sId, @PathVariable String bId)
{
Shop shop = shopRepo.getById(Integer.valueOf(sId));
Barber b = barberRepo.getById(Integer.parseInt(bId));
shop.addBarber(b);
Shop save = shopRepo.save(shop);
return save;
}
}

据我所知,您在Shop实体中使用惰性负载来收集理发师。。。

如果它是从事务中提取的或通过jackson序列化的,这可能会有问题。。。

我建议你可以做一些事情来避免控制台日志中的错误。

1-在服务中加载理发师收藏,就我个人而言,我想创建更多的服务层来与DB Repo层交互,你可以创建ShopService来管理它,你可以通过简单的方法强制加载:shop.getBarbers((.size((;//强制获取同一事务中的实体

2-为每个实体添加@JsonIgnoreProperties({"hibernateLazyInitializer","handler"}(

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

3-set jackson选项在空bean上失败=false。

spring.jackson.serialization.fail-on-empty-beans=false    

ObjectMapper objectMapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

最新更新