在Spring Boot项目中,我有一个JPA实体,如下所示:
@Entity
public class Account {
}
然后我有了查询数据库的存储库:
public interface AccountRepository extends JpaRepository<Account, UUID> {
}
在应用程序和测试中,通过执行以下操作很容易获得存储库:
@Autowired
private AccountRepository accountRepository;
如何在Account类的方法中获取存储库?我试过@Autowired但它没有用。
对于那些争论设计的人,我的问题不是关于设计。我已经在Ruby和Rails以及带有HugSQL的Clojure中编写了这个代码,它是自包含和简洁的:在创建新记录时,我还生成一个紧凑的唯一字母数字id。在Ruby on Rails中,我将其作为库发布:https://github.com/pupeno/random_unique_id
答案 0 :(得分:0)
我猜你正试图在Hibernate中实现类似Active Record pattern
的东西。这很不寻常,但您可以使用@Configurable对您的实体进行注释,以便内部@Autowired
能够工作(同时确保实体包在@ComponentScan范围内)
答案 1 :(得分:0)
您必须使用@GenericGenerator
和@GeneratedValue
查看示例here。请注意,在IdentifierGenerator
实现中,您可以访问存储库。
如果这是针对非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;
}
实体(如上所述here)
{{1}}
答案 2 :(得分:0)
您可以从静态方法访问Spring Application Context
并使用此静态方法在您的@Entity
类中加载您的存储库bean,而不是自动装配它。
您需要创建以下类(找到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();
}
}
然后
@Entity
public class Account {
//your code
public void doAccountRepositoryStuff() {
AccountRepository accountRepository = (AccountRepository) SpringConfiguration.contextProvider().getApplicationContext().getBean("accountRepository");
// Do your own stuff with accountRepository here...
}
}
答案 3 :(得分:0)
我有同样的问题,发现this Github repository。
以下是部分代码:
...
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;
de.ck35.example.ddd.jpa.SpringEntityListener
中Javadoc
目的的描述:
/**
* 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);
}
还有一种配置可以启用嵌套在类(在本例中为实体)中的存储库定义:
@Configuration
@EnableJpaRepositories(basePackages="de.ck35.example.ddd.jpa", considerNestedRepositories=true)
@ComponentScan("de.ck35.example.ddd.jpa")
public class JpaConfiguration {
感谢此存储库的作者Christian Kaspari。
答案 4 :(得分:0)
我在项目中看到了下面的方法,因为该项目没有Service层。老实说,我建议添加Service层而不是这些解决方案,但是如果您确实要/必须使用它,请参见下面的解决方案。
创建存储库界面
public interface BookRepository extends JpaRepository<Book, String> {
}
创建组件
@Component
public class Registry {
private static BookRepository bookRepository;
static BookRepository bookRepo() {
return bookRepository;
}
}
通过使用组件中的静态功能实现回购
import static com.x.Registry.bookRepo;
@Entity
class Book {
public static List<Book> all() {
return bookRepo().findAll();
}
}