【发布时间】:2022-09-28 11:19:17
【问题描述】:
我最近尝试在我的网上商店项目中实现 Spring Security 以区分单个用户。网站运行正常,但有一个我无法跟踪解决的问题。我在User 类中有一个名为Customer 的对象。 Customer 对象具有 id、balance 等字段,而 User 与 OneToOne 具有 Customer 关系,因此我可以拥有单个对象作为凭据和外键到用户的具体信息 - 他的第一个姓名、姓氏、余额、拥有的产品等。
我还有Product 类,它与Customer 有ManyToOne 关系。它有自己的id、productCost 等。
我正在使用 Spring MVC 来处理正确的 URL 调度。当采取一些行动时,我使用@AuthenticationPrincipal 注释来获取当前记录的Customer(通过User 中的外键)并修改与该外键链接的Customer 相关的数据。
当我在控制器中通过@AuthenticationPrincipal 修改Customer 数据时,更改会立即出现并显示在网站上。但是当我尝试通过某些 DAO 修改数据时,例如通过搜索 Customer 到 id 或尝试从 Product getter 中获取拥有 Product 的 Customer(ManyToOne 引用了拥有 @987654348 @),更改不会立即发生。与第一种情况一样,数据库会立即正确更新自身,但代码和网站状态中的集合不会更改直到我注销并再次登录 - 那是更新数据的时候。我怀疑这可能是因为更新UserDetails 直接为当前登录的用户更新数据,但是 - 我如何才能为id 找到的Customer 实现相同的效果?
代码片段: 用户.java:
@Entity
@Table(name=\"users\")
public class Users {
@Id
@Column(name=\"username\")
private String username;
@Column(name=\"password\")
private String password;
@Column(name=\"enabled\")
private boolean isActive;
@OneToMany(mappedBy=\"user\")
private Set<Authorities> authorities;
@OneToOne
@JoinColumn(name=\"customer_id\")
private Customer customer;
产品.java:
@Entity
@Table(name=\"product\")
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name=\"id\")
private int id;
@Column(name=\"name\")
private String productName;
@Column(name=\"description\")
private String productDescription;
@Column(name=\"category\")
private String productCategory;
@Column(name=\"cost\")
private int productCost;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name=\"owner_id\")
private Customer productOwner;
客户.java:
@Entity
@Table(name=\"customer\")
public class Customer {
//Class fields
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name=\"id\")
private int id;
@Column(name=\"balance\")
private int balance;
@Column(name=\"first_name\")
private String firstName;
@Column(name=\"last_name\")
private String lastName;
@Column(name=\"email\")
private String email;
@OneToMany(mappedBy=\"productOwner\", fetch=FetchType.EAGER)
private List<Product> ownedProducts;
一段控制器代码:
@Autowired
CustomerService customerService;
@Autowired
ProductService productService;
/*(...)*/
@GetMapping(\"/showOffer/{offerId}\")
public String getOffer(@PathVariable int offerId, Model theModel, @AuthenticationPrincipal MyUserDetails user) {
Product retrievedProduct = productService.findById(offerId);
if (user.getCustomer().getBalance() >= retrievedProduct.getProductCost())
{
Customer retrievedProductOwner = retrievedProduct.getProductOwner();
/* This is where changes aren\'t applied immediately and I need to logout and login to process them. */
retrievedProductOwner.setBalance(1000);
/* This is where changes are immediately shown and Java collections are updated: */
user.getCustomer().setBalance(user.getCustomer().getBalance()-retrievedProduct.getProductCost());
/* Code below is an attempt to force immediate changes by updating collections directly from database - but that approach doesn\'t work */
productService.delete(retrievedProduct.getId());
retrievedProduct.getProductOwner().getOwnedProducts().clear();
retrievedProduct.getProductOwner().setOwnedProducts(productService.listOwnerProducts(retrievedProduct.getProductOwner()));
}
else {
System.out.println(\"Insufficient funds!\");
}
return \"redirect:/home\";
TL:博士
我在控制器中使用UserDetails 对象,并且我还使用DAO 将Customer 用作UserDetails 中的外键。使用UserDetails 直接更新数据并且一切正常,使用DAO 在我注销并登录之前不会进行更改。
-
你到底想做什么?您没有调用任何持久化方法来存储更改的实体。
标签: java spring spring-mvc spring-security