我有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
的所有属性,并且仅包含其关联的ClassB
和ClassC
实例的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对象的构造函数。
我希望这个例子能给你