[英]How can I access the repository from the entity in Spring Boot?
In a Spring Boot project I have a JPA entity, like this:在 Spring Boot 项目中,我有一个 JPA 实体,如下所示:
@Entity
public class Account {
}
and then I have the repository to query the database:然后我有存储库来查询数据库:
public interface AccountRepository extends JpaRepository<Account, UUID> {
}
In both the app and tests it's easy to get the repository by doing:在应用程序和测试中,通过执行以下操作可以轻松获取存储库:
@Autowired
private AccountRepository accountRepository;
How can I get hold of the repository in a method in the Account class?如何在 Account 类的方法中获取存储库? I tried @Autowired but it didn't work.
我试过@Autowired,但没有用。
For those arguing about design, my question is not about design.对于那些争论设计的人,我的问题与设计无关。 I have written this code in Ruby and Rails as well as Clojure with HugSQL and it was self contained and concise: when creating a new record I also generate a compact unique alphanumeric id.
我已经用 Ruby 和 Rails 以及 Clojure 和 HugSQL 编写了这段代码,它是独立且简洁的:在创建新记录时,我还生成了一个紧凑的唯一字母数字 id。 In Ruby on Rails I released it as a library: https://github.com/pupeno/random_unique_id
在 Ruby on Rails 中,我将其作为库发布: https : //github.com/pupeno/random_unique_id
You can access the Spring Application Context
from static method and use this static method to load your repository bean in your @Entity
class instead of autowiring it.您可以从静态方法访问
Spring Application Context
,并使用此静态方法将存储库 bean 加载到@Entity
类中,而不是自动装配它。
You need to create the following classes (found here ):您需要创建以下类(可在此处找到):
ApplicationContextProvider应用上下文提供者
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public ApplicationContext getApplicationContext() {
return context;
}
@Override
public void setApplicationContext(ApplicationContext ctx) {
context = ctx;
}
}
SpringConfiguration弹簧配置
@Configuration
public class SpringConfiguration {
@Bean
public static ApplicationContextProvider contextProvider() {
return new ApplicationContextProvider();
}
}
And then进而
@Entity
public class Account {
//your code
public void doAccountRepositoryStuff() {
AccountRepository accountRepository = (AccountRepository) SpringConfiguration.contextProvider().getApplicationContext().getBean("accountRepository");
// Do your own stuff with accountRepository here...
}
}
I had same question and found this Github repository .我有同样的问题,并找到了这个 Github 存储库。
Here are some parts of code:以下是部分代码:
...
import de.ck35.example.ddd.jpa.SpringEntityListener;
...
@Entity
@Table(name="bookshelf")
@EntityListeners(SpringEntityListener.class)
public class BookshelfEntity implements Bookshelf {
...
private String category;
@Autowired transient BookRepository bookRepository;
@Autowired transient BookshelfSpaceRepository bookshelfSpaceRepository;
Where de.ck35.example.ddd.jpa.SpringEntityListener
purpose is described in Javadoc
: Javadoc
描述了de.ck35.example.ddd.jpa.SpringEntityListener
用途:
/**
* Entity listener which allows dependency injection inside entities.
* The listener can be registered via {@link EntityListeners} annotation.
*
* Dependency injection annotations like {@link Autowired} are supported.
*
* @author Christian Kaspari
* @since 1.0.0
*/
public class SpringEntityListener {
...
@PostLoad
@PostPersist
public void inject(Object object) {
AutowireCapableBeanFactory beanFactory = get().getBeanFactory();
if(beanFactory == null) {
LOG.warn("Bean Factory not set! Depdendencies will not be injected into: '{}'", object);
return;
}
LOG.debug("Injecting dependencies into entity: '{}'.", object);
beanFactory.autowireBean(object);
}
There is also configuration which enables Repositories definitions nested in classes (in this case entities):还有配置可以启用嵌套在类中的存储库定义(在本例中为实体):
@Configuration
@EnableJpaRepositories(basePackages="de.ck35.example.ddd.jpa", considerNestedRepositories=true)
@ComponentScan("de.ck35.example.ddd.jpa")
public class JpaConfiguration {
Thanks to Christian Kaspari who is author of this repository.感谢这个存储库的作者Christian Kaspari 。
I'm guessing you are trying to implement something like the Active Record pattern
in Hibernate.我猜你正在尝试在 Hibernate 中实现类似
Active Record pattern
东西。 It's quite unusual but you could annotate your entity with @Configurable so you can get internally @Autowired
to work (Also ensure entity package is within your @ComponentScan reach)这很不寻常,但您可以使用@Configurable注释您的实体,这样您就可以在内部使用
@Autowired
工作(还要确保实体包在您的@ComponentScan范围内)
You have to use @GenericGenerator
and @GeneratedValue
see an example here .您必须使用
@GenericGenerator
和@GeneratedValue
请参阅此处的示例。 Please notice that in the IdentifierGenerator
implemntation you can access the repository.请注意,在
IdentifierGenerator
实现中,您可以访问存储库。
If this is for non-id field, then the work around will be to make a new entity GeneralSequenceNumber
and its ID is the required generated ID, then make one to one mapping between GeneralSequenceNumber
and your Account
entity (as mentioned here )如果这是不id字段,然后周围的工作将是使一个新的实体
GeneralSequenceNumber
其ID是需要生成的ID,然后做一个到之间的一个映射GeneralSequenceNumber
和您的Account
实体(如提到这里)
@Entity
public class GeneralSequenceNumber {
@Id
@GenericGenerator(name = "sequence_dep_id", strategy = "com.xyz.ids.DepartmentIdGenerator")
@GeneratedValue(generator = "sequence_dep_id")
@Column(name="Department_Id")
private String deptId;
}
@Entity
public class Account {
@Id ..
private Long id;
@OneToOne(...)
private GeneralSequnceNumber myVal;
}
I saw the method below in a project because there were no Service layer at that project.我在一个项目中看到了下面的方法,因为该项目没有Service层。 To be honest, I recommend adding Service layer instead of these solutions but if you really want/have to use it, the solution is below.
老实说,我建议添加服务层而不是这些解决方案,但如果您真的想要/必须使用它,则解决方案如下。
Create Repository Interface创建存储库接口
public interface BookRepository extends JpaRepository<Book, String> {
}
Create a Component创建组件
@Component
public class Registry {
private static BookRepository bookRepository;
static BookRepository bookRepo() {
return bookRepository;
}
} }
Achieve the repo by using static function in the Component在组件中使用静态函数实现repo
import static com.x.Registry.bookRepo;
@Entity
class Book {
public static List<Book> all() {
return bookRepo().findAll();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.