简体   繁体   English

如何从 Spring Boot 中的实体访问存储库?

[英]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.

相关问题 如何从实体类 spring boot 生成 CRUD 存储库类 - How to generate CRUD repository class from entity class spring boot 如何在 spring 引导中使用分页对存储库实体进行排序 - How to sorting repository entity with pagination in spring boot 使用spring数据jpa的spring boot。 如何从请求主体执行实体的部分更新? - Spring boot with spring data jpa. How can i perform partial update of entity from request body? 如何在 Spring Boot 中实现通用 JPA 存储库 - 它可以自动装配到任何实体/类类型的 spring 服务中 - How to implement Generic JPA Repository in Spring Boot - Which can be autowired into spring services for any entity/class type 如何使用 Spring 引导在 JPA 存储库中编写 SQL 查询? - How can I write SQL query in JPA repository with Spring Boot? 我如何处理实体中的任何更改字段(Spring Boot) - How I can handle any change field in Entity (Spring Boot) 如何引用实体中的视图? (春季启动) - How can I reference a view in the entity? (Spring Boot) 如何在 Spring Boot JPA 中从列实体调用分页存储库 - How to make a paginated repository call from column entity in Spring Boot JPA 我无法保存实体(Spring Boot 应用程序) - I can not save entity (Spring Boot Application) 当我认为我可以从 Spring 中的实体访问服务时,替换我的代码的更好解决方案是什么? - How is the better solution to replace my code, when I think i can access service from entity in Spring?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM