2016-03-10 3 views
3

Я использую Spring Roo для генерации моих сущностей и обработки его с помощью сущ. ManManager, а также сохраняющихся и других методов через классы AspectJ. Теперь я пытаюсь использовать Spring бутсу, чтобы сделать что-то простое, что будет писать вещи в базу данных ...Как использовать Spring Spring с JPA

@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; 
    } 

Когда я звоню сохраняются или слияния, 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» o r автоматически создать сущностьManager?

ответ

7

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

Я думаю, что вы можете искать в Spring Data Repositories. Я бы рекомендовал прочитать это, чтобы получить основы.

Чтобы начать работу с хранилищами:

Первое, что я бы хотел бы удалить transient EntityManager entityManager; и ваши persist/merge функции из вашего Account класса.

Внутри вашего класса Application вы можете добавить аннотацию @EnableJpaRepositories.

Далее создайте новый Interface (не новый класс), это будет ваш репозиторий Account.

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

Где Account это тип Entity и Long типа идентификатора Account

Есть несколько репозиториев интерфейсов с различной поддержка включена с пружинящими данными, которые унаследованы из Repository.

Не добавляя ничего к вашему интерфейсу, PagingAndSortingRepository предоставит вам поддержку CRUD-операций и подкачки.

Его также можно добавить пользовательские запросы к вашему интерфейсу с помощью JPQL, посмотрите аннотацию @Query. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

Теперь вы можете использовать @AutowireAccountRepository в любой из ваших управляемых зерен Spring и начать сохранять и извлекать данные.

+1

Ничего себе, это намного отличается от того, как это делает Spring Roo, но много чистых и по сравнению со всеми созданными файлами AspectJ. Спасибо за очень подробный ответ! –

+2

Roo основан на шаблоне Active Record, где сущности могут управлять собой. Данные Spring основаны на шаблоне репозитория, где отдельный объект отвечает за управление объектами домена. – gregturn

2

Try замена:

@Configuration 
@ComponentScan 
@EnableAutoConfiguration 

с:

@SpringBootApplication 

Смотрите эту article

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

+1

'@ SpringBootApplication' был просто добавлен для удобства, это эквивалентно добавлению' @Configuration, @ComponentScan, @ EnableAutoConfiguration'. https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html – francis

1

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

  1. EntityManager запись не @Autowired и даже если он был @Entity не признаются в качестве пружинного компонента и по этой причине инъекции зависимости служба пружины Ждет» т работа
  2. , так что, как я сказал ранее фасоль с аннотацией @Entity не весной фасоли и по этой причине не могут воспользоваться @Transactional аннотацию

вы можете использовать проект Spring DataJPA в этом case помнить configure tis wit ч @EnableJpaRepositories или вы можете создать свой репозиторий организации кода таким образом

Entity:

@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; 
.... 

}

Repository слой:

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

@SpringBootApplication 
@EnableTransactionManagement 
class ApplicationConfig { 

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

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