JPA: How to get entity based on field value other than ID?

前端 未结 15 923
时光说笑
时光说笑 2020-12-04 21:08

In JPA (Hibernate), when we automatically generate the ID field, it is assumed that the user has no knowledge about this key. So, when obtaining the entity, user would query

相关标签:
15条回答
  • 2020-12-04 21:30

    In my Spring Boot app I resolved a similar type of issue like this:

    @Autowired
    private EntityManager entityManager;
    
    public User findByEmail(String email) {
        User user = null;
        Query query = entityManager.createQuery("SELECT u FROM User u WHERE u.email=:email");
        query.setParameter("email", email);
        try {
            user = (User) query.getSingleResult();
        } catch (Exception e) {
            // Handle exception
        }
        return user;
    }
    
    0 讨论(0)
  • 2020-12-04 21:33

    I solved a similar problem, where I wanted to find a book by its isbnCode not by your id(primary key).

    @Entity
    public class Book implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
        private String isbnCode;
    
    ...
    

    In the repository the method was created like @kamalveer singh mentioned. Note that the method name is findBy+fieldName (in my case: findByisbnCode):

    @Repository
    public interface BookRepository extends JpaRepository<Book, Integer> {
    
        Book findByisbnCode(String isbnCode);
    }
    

    Then, implemented the method in the service:

    @Service
    public class BookService {
    
        @Autowired
        private BookRepository repo;
        
        
        public Book findByIsbnCode(String isbnCode) {
            Book obj = repo.findByisbnCode(isbnCode);
            return obj; 
        }
    }
    
    0 讨论(0)
  • 2020-12-04 21:33

    Have a look at:

    • JPA query language: The Java Persistence Query Language
    • JPA Criteria API: Using the Criteria API to Create Queries
    0 讨论(0)
  • 2020-12-04 21:37

    Best practice is using @NaturalId annotation. It can be used as the business key for some cases it is too complicated, so some fields are using as the identifier in the real world. For example, I have user class with user id as primary key, and email is also unique field. So we can use email as our natural id

    @Entity
    @Table(name="user")
    public class User {
      @Id
      @Column(name="id")
      private int id;
    
      @NaturalId
      @Column(name="email")
      private String email;
    
      @Column(name="name")
      private String name;
    }
    

    To get our record, just simply use 'session.byNaturalId()'

    Session session = sessionFactory.getCurrentSession();
    User user = session.byNaturalId(User.class)
                       .using("email","huchenhai@qq.com")
                       .load()
    
    0 讨论(0)
  • 2020-12-04 21:38

    Basically, you should add a specific unique field. I usually use xxxUri fields.

    class User {
    
        @Id
        // automatically generated
        private Long id;
    
        // globally unique id
        @Column(name = "SCN", nullable = false, unique = true)
        private String scn;
    }
    

    And you business method will do like this.

    public User findUserByScn(@NotNull final String scn) {
        CriteriaBuilder builder = manager.getCriteriaBuilder();
        CriteriaQuery<User> criteria = builder.createQuery(User.class);
        Root<User> from = criteria.from(User.class);
        criteria.select(from);
        criteria.where(builder.equal(from.get(User_.scn), scn));
        TypedQuery<User> typed = manager.createQuery(criteria);
        try {
            return typed.getSingleResult();
        } catch (final NoResultException nre) {
            return null;
        }
    }
    
    0 讨论(0)
  • 2020-12-04 21:42

    Refer - Spring docs for query methods

    We can add methods in Spring Jpa by passing diff params in methods like:
    List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

    // Enabling static ORDER BY for a query 
    
    List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
    
    0 讨论(0)
提交回复
热议问题