spring data JPA - mysql - findById() empty unless findAll() called before

瘦欲@ 提交于 2020-05-13 05:26:27

问题


I'm struggling with this strange error: the findById() method of a CrudRepository returns Optional.empty, unless findAll() is called before when using mysql.

e.g.

User

@Entity
public class User {

    @Id
    @GeneratedValue
    private UUID id;

    public UUID getId() {
        return id;
    }

}

UserRepository

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

UserService

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public UUID create() {
        final User user = new User();
        userRepository.save(user);
        return user.getId();
    }

    @Transactional
    public User find(@PathVariable UUID userId) {
        // userRepository.findAll(); TODO without this functin call, Optinoal.empty is returned by the repo
        return userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException(String.format("missing user:%s", userId)));
    }
}

UserApp

@SpringBootApplication
public class UserApp {

    private static final Logger LOG = LoggerFactory.getLogger(UserApp.class);

    @Autowired
    private UserService userService;

    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        final UUID userId = userService.create();
        final User user = userService.find(userId);
        LOG.info("found user: {}", user.getId());
    }

    public static void main(String[] args) {
        SpringApplication.run(UserApp.class, args);
    }

}

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/db_test
spring.datasource.username=springuser
spring.datasource.password=ThePassword

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.database=mysql

Why does the findAll() method call change the result of findById()?

Edit: Hibernate logs with findAll:

Hibernate: drop table if exists user
Hibernate: create table user (id binary(255) not null, primary key (id)) engine=MyISAM
Hibernate: insert into user (id) values (?)
Hibernate: select user0_.id as id1_0_ from user user0_

Without:

Hibernate: drop table if exists user
Hibernate: create table user (id binary(255) not null, primary key (id)) engine=MyISAM
Hibernate: insert into user (id) values (?)
Hibernate: select user0_.id as id1_0_0_ from user user0_ where user0_.id=?

回答1:


Try to use below code;

@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Type(type="uuid-char")
private UUID id;



回答2:


I was facing the same issue. The root cause was the mismatch between non-nullable @ManyToOne relation and the data persisted in table. I had this:

@ManyToOne(optional = false)
  @JoinColumn(name="batch_id")
  private Batch batch;

which means batch_id can't be null in any row. However, my rows had null value for batch_id foreign key. After removing optional = false (which is the expected business rule), findById started working as expected.

Got indication from this thread: I tired to do something with JpaRepository But Can not find row with findById ,




回答3:


You have not declared findById method in user repository and also use @Repository annotation. It should be like this

    @Repository("UserRepository")
    public interface UserRepository extends CrudRepository<User, UUID> { 
         User findById(UUID id);
    }


来源:https://stackoverflow.com/questions/57795044/spring-data-jpa-mysql-findbyid-empty-unless-findall-called-before

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!