2011-09-02 49 views
0

这个问题有些与JPA有关,但更多的是关于方法而不是技术,所以希望有人能够提供建议。Spring MVC + JPA - 绑定/更新关联实体

我正在使用Spring MVC和Hibernate来为一个允许用户创建产品和产品说明的网站提供支持。我有一个Product实体,它与ProductDescription具有双向一对多关系。

如果在提交绑定到Product的实例并指定其所有ProductDescription的表单时,恶意用户可能会输入ProductDescriptions的伪造ID并“劫持”其他用户的数据。解决这个问题的方法之一是始终创建ProductDescription,然后在提交表单时删除它们,并且每次都创建新的表单。这似乎效率低下,因为每次更新产品时都会需要额外的删除和写入操作(即使ProductDesciptions未更改)。

另一种选择是在运行更新之前检查子实体的“所有权”。

其他人如何解决此问题?大多数人是否会删除/插入或选择性更新?

这里是我说的那种POST提交的例子:

id=1 
name=My Product 
descriptions[0].id=123 
descriptions[0].text=A lovely description of my product 
descriptions[0].price=100 
descriptions[1].id=123 
descriptions[1].text=Another lovely description of my product in another language 
descriptions[1].price=50 

而且我说的那种类的一个例子:

public class Product 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id; 
    @OneToMany(mappedBy = "product") 
    private Set<ProductDescription> descriptions; 
    private String name; 
} 


public class ProductDescription 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id; 
    private Integer price; 
    @ManyToOne 
    private Product product; 
    private String text; 
} 

回答

2

如果您倾向于将安全性添加到您的应用程序中,我会建议使用spring安全性,并且在更新其值之前,如果用户是该产品的所有者,您可以检查servlet。

这就是我们迄今为止所做的。通过在服务器端进行检查浪费了一点资源,但只有高级用户可以通过更改响应头来尝试,因此我不认为这会发生很多。

如果没有安全性,您可以尝试使用会话来验证用户,但问题是如果会话不存在,则无法更改产品。

干杯

+0

我想这就是我们要做的。我们支持PHP表示层,因此不能直接访问会话,否则我们可以将其绑定并使用会话群集。 –

2

你有没有考虑使用数据传输对象(DTO)?这样你可以将DTOs而不是实体对象传递给中间层,并且在那里你可以执行多次检查。