Как сохранить при использовании Spring Boot с JPA

Я привык использовать Spring Roo для создания моих сущностей и его обработки путем инъекции entityManager, а также persist и других методов через классы 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, очевидно, равен нулю.

Я также попытался добавить implements CrudRepository<Account, Long> до Account класс, чтобы увидеть, что он даст мне эту функциональность по умолчанию Реализация, но то, что я получаю, - это просто пустые классы, которые нужно заполнить.

Я посмотрел на документы Spring Boot, они покрывают его очень кратко, опуская достаточно деталей, чтобы не было очевидно, что мне не хватает.

у меня есть класс приложения, который загружает приложение:

@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, и если то, что я сделал, правильно до сих пор, как мне "autowire" или автоматически создать entityManager?

3 ответов


в вашем примере Ваш EntityManager всегда будет null. Весна не будет автоматически провод один в ваш Entity класса. Я также не уверен, что ваша цель здесь, но я готов поспорить, что вы, скорее всего, не хотите иметь свой Entity придержи EntityManager

я думаю, что вы, возможно, ищете Хранилища Данных Spring. Я бы рекомендовал прочитать это, чтобы получить основы.

чтобы начать работу с репозиториями:

первый то, что я бы сделал, было бы remove transient EntityManager entityManager; и свой persist/merge функции из Account класса.

внутри


попробуйте заменить:

@Configuration
@ComponentScan
@EnableAutoConfiguration

С:

@SpringBootApplication

посмотреть этот статьи

в частности: по умолчанию Spring Boot включит поддержку репозитория JPA и посмотрит в пакете (и его подпакетах), где находится @SpringBootApplication. Если ваша конфигурация имеет определения интерфейса репозитория JPA, расположенные в невидимом пакете, вы можете указать альтернативные пакеты, используя @EnableJpaRepositories и его тип-safe basePackageClasses=MyRepository.параметр класса.


проблема в ваш код:

  1. запись EntityManager не была @Autowired, и даже если она была @Entity не распознается как spring bean, и по этой причине служба впрыска зависимостей spring не работала
  2. С тех пор, как я сказал ранее, Боб, аннотированный @Entity, не является весенним Бобом, и по этой причине вы не можете воспользоваться аннотацией @Transactional

вы можете использовать проект Spring DataJPA в этом случае помните настройте tis с помощью @EnableJpaRepositories или вы можете создать свой репозиторий, организующий ваш код таким образом

сущности:

@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 boot @EnableTransactionManagement в интересах управления транзакциями

@SpringBootApplication
@EnableTransactionManagement
class ApplicationConfig {

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

Я надеюсь, что это может помочь вам. (Орфография исправлена 2018-02-24)