简体   繁体   中英

Data doesn't update immediately after changes in tables

I've recently tried to implement Spring Security into my web store project to distinguish between single users. Websites are working properly except there is one issue which I can't track to resolve. I have object called Customer within User class. Customer object has fields like id , balance , etc., and User has OneToOne relationship to Customer , so I can have single object for credentials and foreign key to specifics of user - his first name, last name, balance, owned products, etc.

I also have Product class which has ManyToOne relationship with Customer . It has its' own id , productCost , etc.

I'm using Spring MVC to take care of proper URL dispatching. When some action is taken, I'm using @AuthenticationPrincipal annotation to get currently logged Customer (through foreign key in User ) and modify data regarding Customer linked with that foreign key.

When I modify Customer data through @AuthenticationPrincipal in controller, changes are immediate and they show up on website. But when I try to modify data through some DAO, for example by searching for Customer through id or try to get Customer that owns Product from Product getter ( ManyToOne has reference to owning Customer ), changes are not immediate. Database updates itself immediately and properly, like in first case, but collections in code and website state are not changed until I logout and login again - that's when data is updated. I suspect it may be due to fact that updating UserDetails updates data directly for currently logged user but then - how may I achieve same effect for Customer found by id ?

Snippets of code: 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;

Product.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;

Customer.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;

Piece of controller code:

@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 I use UserDetails object in controller and I am also using DAO for Customer used as foreign key in UserDetails . Using UserDetails directly updates data and everything works fine, using DAO doesn't make changes until I logout and login. 在此处输入图像描述

as far as i understand your changes are only commited when you log out. just try to synchronize and commit any modification at the right time and it would be safer that you manage sessions and transactions at the same time so you don't get any sort of incoherence when you do that. then tell me about the results.

  1. Check whether CTRL+F5 in your browser (force cache clearance) updates your data similarly to logging out and back in. If so, it's a question of cached information. (this and (3) may occur at the same time)

  2. Alternatively... or perhaps complementarly... your data fetch reqeust may be called before the database update/commit operation is completed. If so, it should become evident if you run distinct update and show routines. ie turn A into B, then into C, and you'd get something like B when you're expecting C... A instead of B... etc.

  3. Lastly, depending on how you set up your back end, it is possible that you only populate whatever form you use for the front end exactly once, instead of dynamically querying the database whenever you access that form.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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