Как сохранить при использовании 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.параметр класса.
проблема в ваш код:
- запись EntityManager не была @Autowired, и даже если она была @Entity не распознается как spring bean, и по этой причине служба впрыска зависимостей spring не работала
- С тех пор, как я сказал ранее, Боб, аннотированный @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)