Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why findById response is id not found but findAll returns object with this id

I can't find the mistake in my code. Looking for help. Why does the method findById() return no such object with this id but findAll() displays this object with this id?

This is my class User:

@Entity
@Table(name = "users")
public class User {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "login")
    private String login;

    @Column(name = "password")
    private String password;

    @JsonIgnore
    @OneToOne(optional = false, mappedBy = "user")
    private UserDetails userDetails;
}

My class UserDetails:

@Entity
@Table(name = "userdetails")
public class UserDetails {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "surname")
    private String surname;

    @OneToOne(optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id")
    private User user;
}

My controller:

@RestController
public class AnotherUserController {
    private final UserRepository userRepository;

    @Autowired
    public AnotherUserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @GetMapping("/demo/{id}")
    public User findById(@PathVariable("id") Long id) {
        return userRepository.findById(id).orElseThrow(() -> new RuntimeException("user not found: " + id));
    }

    @PostMapping("/demo")
    public User save(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/demo")
    public Iterable<User> save() {
        return userRepository.findAll();
    }
}

My repository:

public interface UserRepository extends CrudRepository<User, Long> {
}

And logs:

2020-07-05 22:11:30.642 ERROR 13200 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 
[Request processing failed; nested exception is java.lang.RuntimeException: user not found: 23] with root cause

java.lang.RuntimeException: user not found: 23
...
..
.

enter image description here

like image 228
Ilja Tarasovs Avatar asked Sep 04 '25 17:09

Ilja Tarasovs


1 Answers

Ok, so you have @OneToOne(optional = false) relation, and as you said in the comments, this field is a problem. Finding by id does not return users, because hibernate does inner join to userdetails, and since there is no matching record - there is no result.

So the fix is simple: if you want your users returned even when they have no relation to details - mark the relation as optional - @OneToOne(optional = true). Hibernate will then generate left outer join instead of inner join.

If the relation is not optional (from business point of view), then you should not allow such situation to happen that there exists a user without details. Making that check on a database level would be the best (non-null foreign keys etc.).

btw findAll returns results, because it translates to select * from users (no joins) and then fetches details lazily if needed

like image 192
Shadov Avatar answered Sep 07 '25 11:09

Shadov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!