2017-06-14 126 views
1

我的实体被映射到数据库表。在弹簧引导应用程序中模拟DB视图

我需要重新映射到其他条件的表。最简单的方法是创建一个数据库视图。

create view person_main_asg as (
select * from person_history 
where asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP 
) 

问题是我没有创建它的权限。

所以我需要在我的spring-boot应用程序中解决这个问题。

谷歌搜索我发现我可以添加一个过滤器到我的实体定义。

@Entity 
@FilterDef(name="person_history_main_asg") 
@Filter(name="person_history_main_asg", condition = "asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP) ") 
@Table(name = "person_history") 
public class Person { 
///... 
} 

现在我需要启用我的过滤器,因为它默认情况下是禁用的。原来,这是一项艰巨的任务。

其中一个solution是使用AOP/AspectJ。在我看来,更多的是一个黑客而不是答案,但主要问题是它需要通过添加我不允许做的javaagent:path/to/aspectjweaver.jar来修改虚拟机参数。

另一种解决方案是实现其目前被定义为一个接口

public interface PersonRepository { 

    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 

所以实现应该是

public interface PersonRepositoryCustom { 
    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 

public interface PersonRepository extends Repository<Person, String>, JpaSpecificationExecutor<Person>, PersonRepositoryCustom { 
} 

public class PersonRepositoryImpl implements PersonRepositoryCustom { 

    @PersistenceContext 
    private EntityManager entityManager; 

    @Autowired 
    private PersonRepository personRepository; 

    public Person findOne(Specification<Person> spec) { 
     Filter filter = (Filter)entityManager.unwrap(Session.class).enableFilter("person_history_main_asg"); 
     Person result = personRepository.findOne(spec); 
     return result; 
    } 

    public Person findOne(String id) { 
     //... 
    } 

    public List<Person> findAll() { 
     //... 
    } 

    public List<Person> findAll(Specification<Person> spec) { 
     //... 
    } 

    //... 
} 

我有几个问题,这个解决方案(除了一个仓库它是散装和沉重的)。

的EntityManager导致以下错误:无类型[javax.persistence.EntityManagerFactory]被定义的排位豆:预期单一匹配豆,但发现4

另外

@Autowired 
private PersonRepository personRepository; 

原因计算器因为它是一个实例PersonRepositoryImpl这是自动装配,但我需要通过Springboot访问默认实现。

那么我如何在我的应用程序中模拟数据库视图?

编辑:

目前我的实体映射到另一个表。 我的实体仓库被定义为

public interface PersonRepository extends Repository<Person, String>, JpaSpecificationExecutor<Person> { 

     T findOne(ID id); 
     List<T> findAll(); 

     Person findByFullLoginEndingWith(String login); 

     List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
     List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 
+0

为什么你需要一个观点呢?只需在存储库中写入一个'find'方法,就可以将@Query(value =“select * from person_history where as_end_date is null or asg_end_date> CURRENT_TIMESTAMP”,nativeQuery = true)'放在它上面并完成。为什么使它更复杂呢。 –

+0

@M。 Deinum如果我实现我的资源库PersonRepositoryImpl,那么我需要提供findAll的实现(规范规范)。所以我需要从规范中提取条件并将它们与我的查询结合起来。我不知道该怎么做。或者可以请您提供一个解决方案草案作为答案。 –

+0

你不需要实现。如问你为什么需要这种观点?没有必要? –

回答

1

你不需要的实现,你不需要过滤器,你不需要一个视图。只需定义一个查询方法并用@Query对其进行注释。

public interface PersonRepository extends JpaRepository { 

    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 

    @Query(value="select * from person_history where asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP", nativeQuery=true) 
    List<Person> findPersonMain(); 
} 

这就是你所需要的,没有自定义实现等作为春节数据JPA会知道如何处理这一点。目前它是一个本地查询,但你可以重写它到一个JPQL。

============================================== =======================

编辑者的Oleg Pavliv:

的解决方案是使用@Where代替@Filter(取自评论的主题)。

@Entity 
@Where(clause = "asg_end_date is null or asg_end_date > GETDATE()) ") 
@Table(name = "person_history") 
public class Person { 
///... 
} 
+0

请检查我的编辑到OP。我的存储库扩展了ReadOnlyRepository和JpaSpecificationExecutor。如果我只是按照你的建议添加一个方法findPersonMain,它将不会被考虑在内。 –

+0

我仍然不明白你为什么需要这个视图,或者你的人被映射到另一个表的事实与此有关。正如我所提到的,你不需要视图。你为什么需要它? –

+0

我的实体映射到Person表。我需要重新映射到另一个表,使用额外的条件来获得相同的结果。最简单的方法是创建一个视图。您的实现不起作用,因为它与扩展ReadOnlyRepository和JpaSpecificationExecutor的当前存储库定义不兼容。如果我只是按照你的建议添加一个方法,它将不会被考虑,结果选择语句将不包含查询条件。 –

相关问题