Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate筛选器未应用于FindOne CRUD操作_Java_Spring Boot_Hibernate Filters - Fatal编程技术网

Java Hibernate筛选器未应用于FindOne CRUD操作

Java Hibernate筛选器未应用于FindOne CRUD操作,java,spring-boot,hibernate-filters,Java,Spring Boot,Hibernate Filters,我的存储库中确实有此hibernate筛选器: @Entity @Audited @DiscriminatorValue(value = "GROUP") @FilterDef(name = "groupACL", parameters = @ParamDef(name = "userId", type = "long")) @Filters({ @Filter(name = "groupACL", condition = "app_group_id IN (SELECT DISTINC

我的存储库中确实有此hibernate筛选器:

@Entity
@Audited
@DiscriminatorValue(value = "GROUP")
@FilterDef(name = "groupACL", parameters = @ParamDef(name = "userId", type = "long"))
@Filters({
    @Filter(name = "groupACL", condition = "app_group_id IN (SELECT DISTINCT APP_GROUP_ID FROM APP_GROUP START WITH APP_GROUP_ID IN (SELECT UG.APP_GROUP_ID FROM USER_GROUP UG JOIN APP_USER AU ON AU.APP_USER_ID = UG.APP_USER_ID WHERE USER_ID=:userId) CONNECT BY PARENT_APP_GROUP_ID = PRIOR APP_GROUP_ID)", deduceAliasInjectionPoints = false) })
public class Group extends AbstractGroup {
它是使用具有以下类的Spring AOP触发的:

@Component
@Aspect
public class ACLFilterAspect {
private static final String GROUP_ACL = "groupACL";

@Autowired
private EntityManager em;

@Before("execution(* com.trendshift.kyn.pug.data.GroupRepository.*(..))")
public void forceFilter() {
    Session hibernateSession = em.unwrap(Session.class);
    ....
    hibernateSession.enableFilter(GROUP_ACL).setParameter("userId", userId);
    }
}
}
我终于有了以下服务:

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class GroupServiceImpl implements GroupService {

  @Autowired
  GroupRepository groupRepository;

  @Override
  public Group findGroupById(long id) {
    Group group = groupRepository.findById(id);
    return group;
  }
}
这些存储库:

@RepositoryRestResource(exported = false)
public interface AbstractGroupRepository<T extends AbstractGroup>
    extends JpaRepository<T, Long>, QueryDslPredicateExecutor<T> {

List<T> findByNameIgnoreCase(String name);

List<T> findByNameAndTypeOrderByNameAsc(String name, String type);

List<T> findByIdOrderByNameAsc(Long id);

AbstractGroup findById(Long id);
@RepositoryRestResource(exported=false)
公共接口抽象组存储库
扩展JpaRepository、QueryDSL谓词执行器{
列出findByNameIgnoreCase(字符串名称);
列出findByNameAndTypeOrderByNameAsc(字符串名称,字符串类型);
列表findByIdOrderByNameAsc(长id);
抽象组findById(长id);
}

公共接口组存储库
扩展AbstractGroupRepository、GroupRepositoryExtras{
列出findByNameAndCustomerId(字符串名,长customerId);
Iterable findByCustomerIdAndTypeIn(长id,列表类型);
组findById(长id);
}
问题是,当我使用groupRepository.findById(id)时,过滤器被正确应用

如果我使用CRUD核心查询groupRepository。findOne(id)即使在处理Aspect hibernateSession.enableFilter(GROUP_ACL).setParameter(“userId”,userId)之后,也不会应用过滤器; 即使Java启用了过滤器,日志文件也不会在hibernate查询中显示过滤器的任何跟踪

问题似乎只出在.findOne上。芬德尔工作得很好


Hibernate文档中是否有内容表明您无法对findOne方法应用筛选器?

我最后监听了对Crudepository类的任何访问。不确定这是否是最好的方法,但这解决了我的问题

@Component
 @Aspect
public class ACLFilterAspect {
    private static final String GROUP_ACL = "groupACL";

    @Autowired
    private EntityManager em;

    @Before("||execution(* *(..)) && this(com.trendshift.kyn.pug.data.GroupRepository)"
            + "||execution(* *(..)) && this(org.springframework.data.repository.CrudRepository)")

我使用过滤器限制用户根据实体属性访问某些信息。这就是为什么我希望findOne也尊重过滤器

这是我找到的解决这个“问题”的最漂亮的方法


要回答实际问题:

Hibernate文档中是否有说明不能对findOne方法应用过滤器的内容

是的,有。从

过滤器适用于实体查询,但不适用于直接获取。 因此,在下面的示例中,从持久性上下文中获取实体时不考虑过滤器

Spring中for.g SimpleJpaRepository.java的实现使用em.find。因此,请求不会被过滤。 但是如果您以某种方式覆盖实现(例如通过使用投影或编写自定义查询),从而生成查询,则请求将被过滤。
这种行为可能非常令人困惑。

只需重写
findById
,并使用
getById

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer>, SupportedRepositoryOperation<Customer> {

    default Optional<Customer> findById(Long aLong) {
        throw new OperationFindByIdNotAllowedException();
    }

    Optional<Customer> getById(Long id);
}
@存储库
公共接口CustomerRepository扩展了JpaRepository、JpaSpecificationExecutor和SupportedRepository操作{
默认可选findById(长时间){
抛出新操作findByidNotAllowedException();
}
可选的getById(长id);
}

Hi@Cyril你找到解决方案了吗..你确定上面的代码在findOne调用中添加了过滤器吗?我在之前添加了以下代码@(“execution(*org.springframework.data.repository.crudepository.*(..)”),但仍然不起作用。你还有其他建议吗。
  ClassPool pool = ClassPool.getDefault();
  try {
      CtClass cl = pool.get("org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails");
      CtMethod me = cl.getDeclaredMethod("applyRootReturnFilterRestrictions");
      String s = "{final org.hibernate.persister.entity.Queryable rootQueryable = (org.hibernate.persister.entity.Queryable) getRootEntityReturn().getEntityPersister();" + 
              "$1.appendRestrictions(" +
              "rootQueryable.filterFragment(" +
              "entityReferenceAliases.getTableAlias()," +
              "getQueryBuildingParameters().getQueryInfluencers().getEnabledFilters()" +
              "));}";
      me.setBody(s);
      cl.toClass();
  } catch (Exception e) {}
entityManager
.unwrap( Session.class )
.enableFilter( "activeAccount" )
.setParameter( "active", true);

Account account = entityManager.find( Account.class, 2L );

assertFalse( account.isActive() );
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer>, SupportedRepositoryOperation<Customer> {

    default Optional<Customer> findById(Long aLong) {
        throw new OperationFindByIdNotAllowedException();
    }

    Optional<Customer> getById(Long id);
}