Я использую jpa в моем проекте весенней загрузки для операций CRUD. Перед выполнением какой-либо операции я хочу применить фильтр. Я хочу, чтобы один и тот же фильтр применялся ко всем моим объектам, поэтому я написал EntityListener
, который включит фильтр по событиям PrePersist
, PreLoad
и PreRemove
для объекта в процессе работы.
Entity Site
и, возможно, другие объекты расширяют AOrganization
Класс, в котором определен фильтр. Я включаю этот фильтр в EntityListener
. Хотя здесь включается фильтр, он не отражается в результирующем запросе операции.
Пожалуйста, проверьте мой код ниже.
AOrganization. java
import java.io.Serializable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
@MappedSuperclass
@FilterDef(name = "OrgFilter", parameters = { @ParamDef(name = "allowedOrgIdList", type = "long") })
@Filter(name = "OrgFilter", condition = "org_id in (:allowedOrgIdList)")
public class AOrganization implements Serializable {
@ManyToOne()
@JoinColumn(name = "org_id", nullable = true)
private Organization organization;
public Organization getOrganization() {
return organization;
}
public void setOrganization(Organization organization) {
this.organization = organization;
}
}
Сайт. java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "site")
public class Site extends AOrganization{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;
@Column(name = "site_name")
private String siteName;
@Override
public String toString() {
return "Site [id=" + id + ", siteName=" + siteName + "]";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getSiteName() {
return siteName;
}
public void setSiteName(String siteName) {
this.siteName = siteName;
}
}
EntityListener. java
import java.util.Arrays;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import org.hibernate.Filter;
import org.hibernate.Session;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.AbstractEvent;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreDeleteEvent;
import org.hibernate.event.spi.PreDeleteEventListener;
import org.hibernate.event.spi.PreLoadEvent;
import org.hibernate.event.spi.PreLoadEventListener;
import org.hibernate.event.spi.PreUpdateEvent;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.stereotype.Component;
@Component
public class EntityListener implements PreLoadEventListener, PreUpdateEventListener, PreDeleteEventListener {
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_LOAD).appendListener(this);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(this);
registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener(this);
}
@Override
public void onPreLoad(PreLoadEvent event) {
enableOrgFilter(event, event.getEntity());
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
enableOrgFilter(event, event.getEntity());
return false;
}
@Override
public boolean onPreDelete(PreDeleteEvent event) {
enableOrgFilter(event, event.getEntity());
return false;
}
private void enableOrgFilter(AbstractEvent event, Object entity) {
Class clazz = entity.getClass();
boolean isExtendingAOrganization = isExtendingAOrganization(clazz);
if (isExtendingAOrganization) {
Session session = event.getSession();
System.out.println(session);
Filter filter = session.enableFilter("OrgFilter");
filter.setParameterList("allowedOrgIdList", Arrays.asList(2l));
}
}
private boolean isExtendingAOrganization(Class clazz) {
boolean isExtendingFromAOrganization = false;
if (AOrganization.class.isAssignableFrom(clazz)) {
isExtendingFromAOrganization = true;
}
return isExtendingFromAOrganization;
}
}
SiteServiceImpl. java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.Filter;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SiteServiceImpl implements SiteService {
@Autowired
private EntityManager entityManager;
@Autowired
private SiteRepository siteRepository;
@Override
public List<Site> getAllSites() {
Iterable<Site> sites = siteRepository.findAll();
List<Site> allSites = new ArrayList<>();
sites.forEach(allSites::add);
return allSites;
}
@Override
public List<Site> getSiteBySiteName(String siteName) {
Session session = entityManager.unwrap(Session.class);
System.out.println(session);
// Filter filter = session.enableFilter("OrgFilter");
// filter.setParameterList("allowedOrgIdList", Arrays.asList(2l));
List<Site> allSites = siteRepository.findBySiteName(siteName);
return allSites;
}
@Override
public Site updateSiteName(Long id,String siteName) {
Session session = entityManager.unwrap(Session.class);
System.out.println(session);
// Filter filter = session.enableFilter("OrgFilter");
// filter.setParameterList("allowedOrgIdList", Arrays.asList(2l));
Site site = siteRepository.findById(id).get();
List<Site> copy = siteRepository.findBySiteName(site.getSiteName());
if(site == null)
return null;
site.setSiteName(siteName);
siteRepository.save(site);
return site;
}
}
SiteRepository. java
import java.util.List;
import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface SiteRepository extends CrudRepository<Site, Long> {
public List<Site> findBySiteName(String siteName);
public Optional<Site> findById(Long id);
}
Если фильтр включен через EntityListener
, он не работает. Но если я включу фильтр в методе SiteServiceImpl getSiteBySiteName
, он будет работать.
Кроме того, в SiteServiceImpl
изменения фильтра отражаются только для метода findBySiteName
, а не в findById
.
Есть идеи, почему это происходит, или альтернативное решение? Заранее спасибо.