繁体   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