繁体   English   中英

使用Spring Boot和JPA时如何保持

[英]How to persist when using Spring Boot with JPA

我习惯使用Spring Roo来生成我的实体,让它通过AspectJ类处理实体管理以及持久化和其他方法。 现在我正在尝试使用Spring Boot做一些简单的事情,将事情写入数据库......

@Entity
@Table(name = "account")
public class Account { 

  transient EntityManager entityManager;

  @Id
  @GeneratedValue
  private Long id;

  @Column(name = "username", nullable = false, unique = true)
  private String username;

  @Column(name = "password", nullable = false)
  private String password;

  ... getters and setters

  @Transactional
  public void persist() {
    if (this.entityManager == null) this.entityManager = entityManager();
    this.entityManager.persist(this);
  }

  @Transactional
  public Account merge() {
    if (this.entityManager == null) this.entityManager = entityManager();
    Account merged = this.entityManager.merge(this);
    this.entityManager.flush();
    return merged;
  }

当我调用persist或merge时,entityManager显然是null。

我还尝试将implements CrudRepository<Account, Long>Account类,看它会通过默认实现给我这个功能,但我得到的只是需要填写的空类。

我已经看过Spring Boot文档了,他们非常简单地介绍了它,只是省略了足够的细节,以至于我不知道我错过了什么。

我有一个Application类来引导应用程序:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

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

}

我的属性文件如下所示:

spring.application.name: Test Application

spring.datasource.url: jdbc:mysql://localhost/test
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

由于ddl-auto=update属性,将自动创建此数据库

在Spring Boot + JPA中持久化实体的正确方法是什么,如果到目前为止我所做的是正确的,我如何“自动装配”或自动创建entityManager?

在您的示例中,您的EntityManager始终为null。 Spring不会自动将一个连接到您的Entity类。 我也不确定你的目标是什么,但我愿意打赌你很可能不希望你的Entity持有你的EntityManager

我认为您可能正在寻找的是Spring Data Repositories 我建议阅读它以获得基础知识。

要开始使用存储库:

我要做的第一件事就是删除transient EntityManager entityManager; 以及您的Account类中的persist/merge功能。

Application类的内部,您可以添加@EnableJpaRepositories注释。

接下来创建一个新的Interface (不是新类),这将是您的Account存储库。

@Repository
public interface AccountRepository extends PagingAndSortingRepository<Account, Long>

其中AccountEntity的类型, LongAccount的ID类型

存在一些存储库接口,其中包含从Repository继承的Spring Data中包含的各种支持。

在不向接口添加任何内容的情况下, PagingAndSortingRepository将为您提供支持CRUD操作和分页。

它也可以使用JPQL向您的界面添加自定义查询,看看@Query注释。 http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

现在,您可以@Autowire AccountRepository到任何Spring托管bean中,并开始保存和获取数据。

尝试更换:

@Configuration
@ComponentScan
@EnableAutoConfiguration

有:

@SpringBootApplication

看到这篇文章

具体来说:默认情况下,Spring Boot将启用JPA存储库支持并查看@SpringBootApplication所在的包(及其子包)。 如果您的配置包含位于包中的JPA存储库接口定义,则可以使用@EnableJpaRepositories及其类型安全的basePackageClasses = MyRepository.class参数指出备用包。

您的代码中的问题是:

  1. EntityManager条目不是@Autowired,即使它是@Entity也不被识别为spring bean,因此spring的依赖注入服务不起作用
  2. 因为我以前说过用@Entity注释的bean不是一个spring bean,因此你不能从@Transactional注释中受益

在这种情况下,您可以使用Spring DataJPA项目记住使用@EnableJpaRepositories配置tis,或者您可以创建以这种方式组织代码的存储库

实体:

@Entity
@Table(name = "account")
public class Account { 

  @Id
  @GeneratedValue
  private Long id;

  @Column(name = "username", nullable = false, unique = true)
  private String username;

  @Column(name = "password", nullable = false)
  private String password;
.... 

}

存储库层:

public interface AccountRepository {
   void persist();
   Account merge();
}

@Repository
class AccountRepositoryJpaImpl implements AccountRepository {

  @Autowired
  private EntityManager entityManager;

  ...
  @Transactional
  public void persist() {
    if (this.entityManager == null) this.entityManager = entityManager();
    this.entityManager.persist(this);
  }

  @Transactional
  public Account merge() {
    if (this.entityManager == null) this.entityManager = entityManager();
    Account merged = this.entityManager.merge(this);
    this.entityManager.flush();
    return merged;
  }
....
}

@SpringBootApplication有利于Spring引导@EnableTransactionManagement的所有功能,有利于事务管理

@SpringBootApplication
@EnableTransactionManagement
class ApplicationConfig {

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

我希望这可以帮到你。 (拼写纠正2018-02-24)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM