簡體   English   中英

Spring 引導 - 保持多對一 object 返回一個空列表

[英]Spring Boot - Persisting a Many-to-One object returns an empty list

我有兩個模型,用戶和資源。 一個用戶可以擁有很多資源(db中有一個resource_id字段),每個Resource指向數據庫中的一個user_id。 上傳資源后,用戶表中的 resource_id 列仍然為空,當我調用 get 方法獲取所有用戶時,資源的 json 響應為空(“資源”:[])。

用戶model:

@Entity
@Table( name = "users", 
uniqueConstraints = { 
@UniqueConstraint(columnNames = "username"),
@UniqueConstraint(columnNames = "email") })
public class User {

@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid", strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@Type(type="pg-uuid")
private UUID id;

@OneToMany(fetch = FetchType.LAZY, mappedBy="user")
private List<Resources> resources = new ArrayList<>();

public UUID getId() {
    return id;
}

public void setId(UUID id) {
    this.id = id;
}

public List<Resources> getResources() {
    return resources;
}

public void setResources(List<Resources> resources) {
    this.resources = resources;
}

public void addResources(Resources resource) {
    this.resources.add(resource);
    resource.setUser(this);
}
}

資源model:

    @Entity
    @Table(name = "resources")
    public class Resources  extends AuditModel {

    @Id
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid", strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    @Type(type="pg-uuid")
    private UUID id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="owner_id", referencedColumnName="id", nullable=true, insertable=true, updatable=true)
    private User user;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    }

我的控制器:

    @PostMapping("/uploadFile")
public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file, Authentication authentication) {
    User user = userRepository.findByUsername(authentication.getName()).get();
    Resources resource = resourcesStorageService.storeFile(file, user.getId());
    return ResponseEntity.ok(new MessageResponse("File has been uploaded successfully, link to file: " +fileDownloadUri));
    }
  
    @GetMapping("/users")
public List<? extends UserProjection> printUsers(Authentication authentication) {
    User user = userRepository.findByUsername(authentication.getName()).get();
    try {
        boolean hasAuthority = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
        if (hasAuthority) {
            return userRepository.getAllBy();
        }
        return userRepository.getUserProjectionsBy();

    } catch (Exception e) {
        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Full authorization is required." , e);
    }
}

這是存儲文件方法:

   public Resources storeFile(MultipartFile file, UUID id) {
    // Normalize file name
    String fileName = StringUtils.cleanPath(file.getOriginalFilename());
    User user = userRepository.findUsersById(id).get();
    try {
        // Check if the file's name contains invalid characters
        if(fileName.contains("..")) {
            throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
        }

        Resources resources = new Resources(fileName, file.getContentType(), file.getBytes());
        resources.setSize(file.getSize());
        resources.setUser(user);
        user.addResources(resources);
        userRepository.save(user);

        return resourcesRepository.save(resources);
    } catch (IOException ex) {
        throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
    }
}
    

存儲文件后,我的用戶表上的 resource_id 列不會更新,而資源表上的 user_id 列已使用用戶 ID 正確更新。 我已經搜索了大約 2 個小時,並嘗試弄亂很多注釋,但沒有成功。 提前致謝。

如果一個用戶可以擁有很多資源,則不能將多個 id 放在一個 resource_id 列中。 您實際上不需要 resource_id 列來檢索屬於用戶的所有資源。

此外,您正在延遲獲取資源,這意味着您必須調用 object 用戶的屬性才能訪問資源。 如果你想用用戶加載資源,你應該使用 fetch = FetchType.EAGER。

試試吧,我希望它有效^^

您的關系的所有者實體是其中包含@JoinColumn的一方,因此請確保您已為要保存的每個resource實體設置user字段。

嘗試這樣注釋:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM