繁体   English   中英

表更改后数据不会立即更新

[英]Data doesn't update immediately after changes in tables

我最近尝试将 Spring 安全性实施到我的 web 商店项目中以区分单个用户。 网站运行正常,但有一个问题我无法跟踪解决。 我在User class 中有一个名为Customer的 object。 Customer object 具有idbalance等字段,并且UserCustomer具有OneToOne关系,因此我可以拥有单个 object 作为凭据和用户具体信息的外键 - 他的名字,姓氏名称、余额、自有产品等。

我还有Product class,它与CustomerManyToOne关系。 它有自己的idproductCost等。

我正在使用 Spring MVC 来处理正确的 URL 调度。 当采取某些行动时,我使用@AuthenticationPrincipal注释获取当前登录的Customer (通过User中的外键)并修改有关与该外键链接的Customer的数据。

当我在 controller 中通过@AuthenticationPrincipal修改Customer数据时,更改会立即生效并显示在网站上。 但是,当我尝试通过某些 DAO 修改数据时,例如通过id搜索Customer或尝试从Product getter 获取拥有ProductCustomerManyToOne已引用拥有Customer ),更改不会立即生效。 数据库会立即正确地自行更新,就像第一种情况一样,但是代码中的 collections 和网站 state 在我注销并再次登录之前不会更改 - 那是数据更新的时候。 我怀疑这可能是因为更新UserDetails会直接为当前登录的用户更新数据,但是 - 我如何才能为通过id找到的Customer实现相同的效果?

代码片段:Users.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;

一段controller代码:

@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:DR 我在 controller 中使用UserDetails object 并且我也在使用 DAO for Customer作为UserDetails中的外键。 使用UserDetails直接更新数据并且一切正常,使用 DAO 在我注销并登录之前不会进行更改。 在此处输入图像描述

据我了解,您的更改仅在您注销时才会提交。 只需尝试在正确的时间同步和提交任何修改,同时管理会话和事务会更安全,这样您就不会在执行此操作时出现任何不连贯的情况。 然后告诉我结果。

  1. 检查您浏览器中的CTRL+F5(强制清除缓存)是否像注销和重新登录一样更新您的数据。如果是,则为缓存信息的问题。 (这和(3)可能同时发生)

  2. 或者......或者可能是互补......您的数据获取请求可能会在数据库更新/提交操作完成之前被调用。 如果是这样,如果您运行不同的更新和显示例程,它应该变得明显。 即,将 A 转换为 B,然后转换为 C,当您期望 C...A 而不是 B... 时,您会得到类似 B 的结果。

  3. 最后,根据您设置后端的方式,您可能只填充一次用于前端的任何表单,而不是在访问该表单时动态查询数据库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM