简体   繁体   中英

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

I have two models, Users and Resources. A user can have many resources (there is a resource_id field in the db) and each Resource points to a user_id in the database. After uploading a resource, the resource_id column remains empty in the users table and when I call a get method to get all users, the json response of the resources is empty ("resources": []).

User 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);
}
}

Resources 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;
    }
    }

My controllers:

    @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);
    }
}

And here is the store file method:

   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);
    }
}
    

After storing a file the resource_id column on my users table does not get updated while the user_id column on the resources table is correctly updated with the id of the user. I have searched for like 2 hours and tried messing with a lot of annotations but with no luck. Thanks in advance.

If a user can have many resources, you can't put multiple ids in a single resource_id column. You actually don't need the resource_id column to retrieve all the resources belonging to a user.

Also you're fetching the resources lazily, meaning you have to call the property on the object user to access the resources. If you want to load the resources with the user, you should use fetch = FetchType.EAGER.

Try it, i hope it works ^^

The owner entity of your relation is the side which has @JoinColumn in it so here make sure you have set user field for every resource entities being saved.

Try annotating like this:

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

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