简体   繁体   English

插入新实体:Spring Data JPA 与 Hibernate 的 EntityManager

[英]Insert new entity: Spring Data JPA vs. Hibernate's EntityManager

Please, look at the two code examples bellow which I'm going to use in my Spring Boot project.请看下面的两个代码示例,我将在我的Spring Boot项目中使用它们。 They both do merely the same thing - add a new object into users table, represented by User entity with username defined as @Id and a unique constraint imposed on email column (there are some other columns as well, but they are not shown here for brevity).它们都只做同样的事情 - 将一个新对象添加到users表中,由User实体表示, User username定义为@Id和对email列施加的unique约束(还有一些其他列,但此处未显示它们)简洁)。 Note: I can't simply use save() method from CrudRepository , because it merges existing record with new object if they both have the same username value.注意:我不能简单地使用CrudRepository save()方法,因为如果它们都具有相同的username值,它会将现有记录与新对象合并 Instead, I need to insert a new object with appropriate exception thrown for duplicate data persistence.相反,我需要插入一个新对象,并为重复数据持久性抛出适当的异常。

My question is about which option should be given a favor.我的问题是应该给哪个选项一个帮助。 With EntityManager , I don't need to construct SQL statement.使用EntityManager ,我不需要构造 SQL 语句。 Apart from that obvious observation, are there any advantages which one method may offer over the other (especially, in the matter of performance and resources consumption)?除了这个明显的观察之外,一种方法比另一种方法有什么优势(特别是在性能和​​资源消耗方面)?

Also, when I read latest books and tutorials about data persistence in Spring Boot , they mainly focus on Spring Data JPA .此外,当我阅读有关Spring Boot数据持久性的最新书籍和教程时,它们主要关注Spring Data JPA For example, the 5th edition of "Spring in Action" has no word about Hibernate's EntityMnager .例如, “Spring in Action”第 5 版没有关于 Hibernate 的EntityMnagerEntityMnager Does it mean that dealing with Hibernate directly can be regarded as kind of "old school" and should generally be avoided in modern projects?这是否意味着直接处理Hibernate可以被视为一种“老派”并且在现代项目中通常应该避免?

Option #1: Hibernate's EntityManager选项 #1:Hibernate 的 EntityManager

@RestController
@RequestMapping(path = "/auth/register", produces = "application/json")
@Transactional
public class RegistrationController {

    @PersistenceContext
    EntityManager entityManager;

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Map<String, String> registerNewUser(@RequestBody @Valid User newUser) {

        try {
            entityManager.persist(newUser);
            entityManager.flush();
        } catch (PersistenceException ex) {
            // parse exception to find out which constraints have been 
            // broken - either it's duplicate username, email or both
            String message = parseExceptionForConstraintNames(ex);
            throw new ResponseStatusException(HttpStatus.CONFLICT, messsage);
        }
        
        return Collections.singletonMap("message", "Success..."); 
    }

}

Option #2: custom @Query from CrudRepository选项#2:来自 CrudRepository 的自定义 @Query

@RestController
@RequestMapping(path = "/auth/register", produces = "application/json")
public class RegistrationController {

    private final UsersRepository usersRepository;

    @Autowired
    public RegistrationController(UsersRepository usersRepository) {
        this.usersRepository = usersRepository;
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Map<String, String> registerNewUser(@RequestBody @Valid User newUser) {

        try {
            usersRepository.insert(newUser);
        } catch (DataIntegrityViolationException ex) {
            // parse exception to find out which constraints have been 
            // broken - either it's duplicate username, email or both
            String message = parseExceptionForConstraintNames(ex);
            throw new ResponseStatusException(HttpStatus.CONFLICT, message);
        }
        
        return Collections.singletonMap("message", "Success..."); 
    }

}
public interface UsersRepository extends CrudRepository<User, String> {

    @Modifying
    @Transactional
    @Query(nativeQuery = true, value = "INSERT INTO users (username, email) " +
            "VALUES (:#{#user.username}, :#{#user.email})")
    void insert(@Param("user") User newUser);

}

See this answer for Using JPA repository vs Entity Manager.这个答案使用JPA库VS实体管理器。

Best practice is to not use Repository directly.最佳实践是不要直接使用 Repository。 use Service layer between controller and repository where you can implement the logic for duplicate entries by checking if the record already exist in DB using findByUsername(String username);controllerrepository之间使用服务层,您可以通过使用findByUsername(String username);检查记录是否已存在于数据库中来实现重复条目​​的逻辑findByUsername(String username); throw exception if it already exist else save() the object in DB如果已经存在则抛出异常,否则save()对象save()到数据库中

With the given requirements, the username filed in the entity never qualifies for the @Id .根据给定的要求,实体中提交的username永远不符合@Id

Why can't u add an explicit id field with some sequence generator for the id filed and just keep the username marked with unique constraint only.为什么不能为 id 字段添加带有一些序列生成器的显式 id 字段,而只保留username标记为unique约束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Data JPA/Hibernate - 使用 EntityManager 进行查询 - Spring Data JPA/Hibernate - using EntityManager for queries JPA EntityManager:“查找”与“ createQuery”和“ getResultList” - JPA EntityManager: 'find' vs. 'createQuery' and 'getResultList' JPA / Hibernate Spring @Transactional vs. JOIN FETCH - JPA / Hibernate Spring @Transactional vs. JOIN FETCH Spring 启动 + Hibernate JPA 配置使用EntityManager - Spring Boot + Hibernate JPA configuration to use EntityManager Spring-JPA-Hibernate如何使用EntityManager - Spring - JPA - Hibernate how to use EntityManager Spring 启动 + Hibernate + JPA 没有事务实体管理器可用 - Spring boot + Hibernate + JPA No transactional EntityManager available Spring data JPA Hibernate - EntityManager.executeUpdate or spring repository both fails while using to query/update entity in multi-schema one by one - Spring data JPA Hibernate - EntityManager.executeUpdate or spring repository both fails while using to query/update entity in multi-schema one by one 春季,JPA,休眠3 vs 4 - Spring, JPA, Hibernate 3 vs 4 JPA /休眠的entityManager.persist(..)使实体的集合变为空,即使它们已保存 - JPA/Hibernate entityManager.persist(..) makes the entity's collection to become null even though they are saved 使用Hibernate EntityManager(与Hibernate Core相比)的任何缺点? - Any drawbacks of using Hibernate EntityManager (vs. Hibernate Core)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM