我已将自定义JPA存储库实现为:
class Customer
{
public:
// One for other
Customer (char[MAX] name,int age);
// copy constructor
Customer (const Customer& );
// To print out the customer
void displayCust ();
// Some other useful functions
private:
char *name;
int age;
char sex;
};
enum CustomerType {Senior, Lady, Other};
class CustomerQueue
{
public:
CustomerQueue ();
~CustomerQueue ();
CustomerQueue (const CustomerQueue&);
void enqueue (Customer );
Customer dequeue ();
// four isEmpty functions
bool isGenEmpty () const;
// four printQueue functions
void displayQueue();
// some other useful functions
int getNo ();
private:
struct Node;
typedef Node* NodePtr;
struct Node
{
CustomerType ct;
Customer cust;
NodePtr next;
};
NodePtr head,tail;
};
现在,我想创建一个通用的数据服务:
public class BaseEntity{...}
public class DerivedEntity extends BaseEntity{...}
@NoRepositoryBean
public interface BaseRepository<T extends BaseEntity> extends JpaRepository<T, ID>{
//some common method
}
@Repository
public interface DerivedRepository extends BaseRepository<DerivedEntity>{
}
现在,代码中的某处我想使用save方法:
public class CommonService{
private BaseRepository<? extends BaseEntity> baseRepository;
//wants to use common method by passing derivedRepository
public CommonService(BaseRepository<? extends BaseEntity> derivedRepository) {
this.baseRepository=derivedRepository;
}
}
我收到编译时错误:
无法解析保存
如何解决此问题和设计? 什么是使用通用数据存储库设计公共数据服务的最佳方式?
答案 0 :(得分:0)
有PECS rule:Producer Extends,Consumer Super。这是一个首字母缩略词,可以帮助我们记住何时应该使用super
以及何时应该使用extends
。在这种情况下,save()
方法是消费者。它接收一个对象,但不返回它。所以它应该是super
- 它编译:
private BaseRepository<? super BaseEntity> baseRepository;
// ...
public void foo(BaseEntity entity ) {
baseRepository.save(entity);
}
但是,JpaRepository
也有生产者方法,例如findAll()
。如果您的CommonService
也使用了这个,那么此private BaseRepository<? super BaseEntity> baseRepository;
将毫无用处。
还有一种解决方法:您可以在服务级别指定实体类型,并在方法级别更灵活:
public static class CommonService {
private BaseRepository<BaseEntity> baseRepository;
public CommonService(BaseRepository<BaseEntity> derivedRepository) {
this.baseRepository = derivedRepository;
}
// here you can accept any subtype you want
public <T extends BaseEntity> void foo(T entity) {
baseRepository.save(entity);
}
// you can be flexible here
public List<? super BaseEntity> bar() {
return baseRepository.findAll();
}
}
不幸的是,这些extends
以及super
和?
标志中的大多数都会使此代码的用户感到困难。我建议尽量保持简单。如果这还不够,那么您可以使用泛型,直到找到满足您需求的解决方案 。这将是最简单的解决方案:
// accepts subclasses of BaseEntity
public void foo(BaseEntity entity) {
baseRepository.save(entity);
}
// reutrns a List<BaseEntity>. The _items_ of the list might be subclasses of BaseEntity.
public List<BaseEntity> bar() {
return baseRepository.findAll();
}
实施说明:
以下行未定义ID
类型。这类似于Integer
或Long
- BaseEntity
的字段。
public static interface BaseRepository<T extends BaseEntity> extends JpaRepository<T, ID>