![](/img/trans.png)
[英]Spring JPA how to persist parent when the child is persisted in ManyToMany relationship
[英]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>
其中Account
是Entity
的类型, Long
是Account
的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参数指出备用包。
您的代码中的问题是:
在这种情况下,您可以使用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.