所以我试图建立一个网站使用Spring Boot和React。
到目前为止,我有一个注册表单连接到我的spring后端localhost:8080/api/test/customers(这里有CRUD操作的endpoint)
这很好,我可以从我的React表单将表单数据发布到它,并且我可以在postman中查看它,以从API获得预期的响应。
但现在我在网站上有了另一个表单(一个用户输入姓名、电子邮件和消息的联系表单)。
我在localhost上有这个API:8080/API/form/contact,用于GET和POST请求。
我已经使用1: M关系映射了实体“客户”和“联系表单”,该关系在联系表单表中包含作为FK的客户标识。
问题是,自从我添加了这个,API的响应就不是我所期望的。
邮递员的回复持续了200行,只是嵌套了同样的东西
对客户API的GET请求(注册)
对联系人表单API的GET请求
我的实体类
顾客java-删除了验证注释,使其更易于阅读
@Entity
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="customer_id")
private int customerId;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email_address")
private String emailAddress;
@Column(name="date_of_birth")
private Date dateOfBirth;
@Column(name="mobile_number")
private String mobileNumber;
@Column(name="password")
private String password;
@OneToMany(mappedBy = "customer")
private Set<ContactForm> contactForm;
// default & arg constructor
// getters and setters
}
联系方式。java-删除了验证注释,使其更易于阅读
@Entity
@Table(name="contact_form")
public class ContactForm {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="contact_form_id")
private int id;
@Column(name="name")
private String name;
@Column(name="email_address")
private String emailAddress;
@Column(name="message")
private String message;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
// default and arg constructor
// getters & setters
}
这两个表的MySQL DDL
顾客
CREATE TABLE `customer` (
`customer_id` int NOT NULL AUTO_INCREMENT,
`mobile_number` varchar(12) DEFAULT NULL,
`date_of_birth` date DEFAULT NULL,
`email_address` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`customer_id`)
)
contact_form
CREATE TABLE `contact_form` (
`contact_form_id` int NOT NULL AUTO_INCREMENT,
`email_address` varchar(255) NOT NULL,
`message` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`customer_id` int DEFAULT NULL,
PRIMARY KEY (`contact_form_id`),
FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`)
)
客户控制器类
具有标准endpoint的控制器类,与ContactForm控制器相同
我不能再向任何一个endpoint发布数据了,请有人告诉我为什么会发生这种情况,我想记录下用户和他们以前的所有消息。
无论是否使用DTO,您引用了Customer
,它再次引用了ContactForm
它引用了Customer
,从而导致对对象的递归引用。
避免这种情况的一种简单方法是使用@JsonManagedReference
和@JsonBackReference
,这里介绍了这两种方法。
另一种方法是在子对象上使用@JsonIgnore
,这取决于API的交互方式。
这两者都会告诉Jackson忽略序列化上的子对象。
我强烈建议查看DTO模式,通过REST公开您的域对象,只包含必要的信息。
直接公开ORM实体容易出错,不会抽象API内部,甚至会造成重大安全风险。
例如,创建UserDto
和MessageDto
类:
public class UserDto {
private int customerId;
private List<MessageDto> messages;
}
public class MessageDto {
private String content;
private String recipient;
// other relevant fields
}
并从rest控制器方法返回UserDto
(或其列表)。
您正在描述的实际问题是,您的ORM映射在顾客
和接触表
之间构建了一个循环图。@ManyToOne/@code>@ManyToOne关系似乎无法正常工作。
一般来说,我建议不要以这种循环方式映射实体,而是使它们只能在一个方向上导航(例如,Customer
-
后一个问题是在应用程序增长时出现的,以后可能更难解决:
假设您的应用程序和团队增长,并且多人应该主要独立地处理不同的部分。因此,您需要重构现有的代码库,并创建两个模块:customer
和contact
客户
保存客户的基本数据(姓名、地址、电子邮件等)。它的唯一目的是管理客户的生命周期(创建客户、更改地址或名称、搜索特定客户等)联系人
实现与公司互动的方式:客户的联系人表单、尚未成为您客户的人的联系人表单以及员工回复这些消息的方式。
现在这两个模块应该解耦,因此一个模块中的更改对另一个模块的影响尽可能小
要实现这一点,您应该在两个模块之间只有html" target="_blank">定义良好的依赖关系,而通常模块之间没有循环依赖关系。
如果在此之前构建的代码通过ORM图(或其他方法)在不同“域”的实体之间来回导航,您将很难将这些东西分开。
现在,所有这些都有点遥不可及,仍然无法解决您手头的问题(与@flagalacy answer相反)
如果类之间引入的依赖关系是必要的和有用的,那么我建议只考虑一般的可导航映射,以及进一步的含义。
编辑:详细说明循环映射和更深层映射的问题。
我在显示实体产品和订单项的记录时遇到了大问题。这是一对多关系。 我向产品实体添加了记录,没有任何问题,我在以下函数中执行OrderItem输入: 这似乎没问题,我最大的问题是显示每个产品的所有订单项。关系产品==== 我尝试显示fetchedResult 我知道product中product中的relationship对象是NSSet,如下所示: 我在不同的项目中也用同样的方法,但我真的不知道为什
问题内容: 我正在生成要显示在折线图中的数据。不幸的是,我无法弄清楚如何使上面的查询显示0来表示没有用户注册的日期。所以目前我的输出可能是这样的: 但是我想要的是 我目前确实有一个工作版本,该版本将MySQL结果存储到数组中,然后PHP循环遍历并填补空白。这似乎很混乱,我希望可以通过MySQL解决方案。我已经对该站点进行了很好的搜索,但是努力了解一些实现。有什么建议么? 问题答案: 您可以使用My
我正在为我的项目使用Spring Data JPA(以hibernate作为提供程序),并想知道何时需要实体之间的双向映射? 在我的用例中,我有一个实体,与实体具有关系。目前,我在实体中没有相应的关系。从我所能理解的查看其他帖子,除非我需要通过我的实体/Hibernate删除,否则我可能不需要这样做。我想知道通过双向关系我还能得到什么? 这是我的,不包括访问者: 这是,不包括访问器: 如果我一直在
问题内容: 我们目前正在为一家专业公司内部实施类似于CRM的解决方案。由于所存储信息的性质以及信息的不同值和键,我们决定使用文档存储数据库,因为它非常适合此用途(在这种情况下,我们选择MongoDB)。 作为此CRM解决方案的一部分,我们希望存储实体之间的关系和关联,例如包括存储利益冲突,股东,受托人等的冲突。以最有效的方式将所有这些实体链接在一起,我们确定了“关系”的中心模型是必要的。所有关系都
我们在OpenAM配置中标记了“断言已签名”, 而如果来自IDP的SAML响应经过签名,而SAML断言没有经过签名,OpenAM会把这个SAML响应视为有效的SAML响应吗? 注:openam 版本 13.0.0
我正在学习DDD和六角结构,我想我已经掌握了基本知识。然而,有一件事我不确定如何解决:我如何向用户显示数据? 例如,我得到了一个简单的域,其中包含一个带有某些功能的Worker实体(某些方法会导致实体更改)和一个WorkerRepository,这样我就可以持久化Worker了。我得到了一个应用程序层,其中包含一些命令和命令总线来操作域(比如创建员工和更新他们的工作时间,持久化更改),以及一个基础