Spring MVC:findById-不包括所有ManyToOne集合



我有3个实体。A类、B类和C类。A类与B类和C.类有ManyToOne。

如果我从web浏览器转到/classA/1/classA/abc/1,我得到了非常大的JSON和ClassA以及ClassB和ClassC中的所有项。

但是我只想要ClassA和ClassB的id以及ClassC的id。

哪里有错误?

有一个简化的代码:

/* ------------------------------------------------------ */
@Entity
@Table(name="CLASS_A")
@NamedQuery(name="ClassA.findAll", query="SELECT c FROM ClassA c")
public class ClassA implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private int id;
    @ManyToOne
    @JoinColumn(name="class_b_id", nullable=false)
    private ClassB classB;
    @ManyToOne
    @JoinColumn(name="class_c_id", nullable=false)
    private ClassC classC;
    @Lob
    private String description;
    public ClassA() {
    }
    // getters and setters...
}
/* ------------------------------------------------------ */
@Entity
@Table(name = "CLASS_B")
@NamedQuery(name = "ClassB.findAll", query = "SELECT c FROM ClassB c")
public class ClassB implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(unique = true, nullable = false)
    private int id;
    @Lob
    private String description;
    @OneToMany(mappedBy = "classB")
    private List<ClassA> classesA;
    public ClassB() {
    }
    // getters and setters...
}
/* ------------------------------------------------------ */
Entity
@Table(name = "CLASS_C")
public class ClassC implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(unique = true, nullable = false)
    private int id;
    @Lob
    private String description;
    @OneToMany(mappedBy = "classC")
    private List<ClassA> classesA;
    public ClassC() {
    }
    // getters and setters...
}
/* ------------------------------------------------------ */
@Repository
public class DaoClassA {    
    @Autowired
    private SessionFactory sessionFactory;
    public ClassA findById(int id) {
        return (ClassA) this.sessionFactory.getCurrentSession().
                get(ClassA.class, id);
    }
    public ClassA findByIdMy(int id) {
        return (ClassA) this.sessionFactory.getCurrentSession()
                .createQuery("SELECT n FROM ClassA n LEFT JOIN FETCH n.classB LEFT JOIN FETCH n.classC WHERE n.id = :id").setInteger("id", id)
                .uniqueResult();
    }
}
/* ------------------------------------------------------ */
@Controller
@RequestMapping("/classA")
public class RestController {
    @Autowired
    private ClassAmanager manager;
    @RequestMapping(value="/{id}", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody ClassA get1(@PathVariable("id") int id) {
        return manager.findById(id);
    }
    @RequestMapping(value="/abc/{id}", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody ClassA get2(@PathVariable("id") int id) {
        return manager.findByIdMy(id);
    }
}
/* ------------------------------------------------------ */

一种常见的解决方案是将ClassA实例映射到某种数据传输对象(DTO),然后从控制器返回。

传输对象将包含来自ClassA的所有属性,并且仅包含其关联的ClassBClassC实例的ID,而不是实例本身。

如果你需要一些代码示例来演示这一点,请在评论中告诉我,我会更新答案

更新示例:

public class Foo {
    private int id;
    private Bar bar;
    // Getters and setters
}
public class Bar {
    private int id;
    private String otherProperty1;
    private String otherProperty2;
    // Getters/setters
}
public class FooDto {
    private int id;
    private int barId;
    // Getters and setters
}
public class FooMapper {
    public static FooDto mapToDto(Foo foo) {
        FooDto dto = new FooDto();
        dto.setId(foo.getId());
        dto.setBarId(foo.getBar().getId());
        return dto;
    }
}
// Usage of the mapper in your controller method
return FooMapper.mapToDto(foo);

基本上,通过这样做,您可以将模型对象转换为传输对象,该对象只有您希望在序列化的JSON中看到的属性。

你不必像这样实现它。例如,如果您不想创建Mapper类,您可以将映射逻辑移动到DTO对象的构造函数。

我希望这个例子能给你

的大致概念

最新更新