Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @Target({
- ElementType.TYPE,
- ElementType.METHOD,
- })
- @Retention(RetentionPolicy.RUNTIME)
- public @interface PreCollectionChange {
- }
- public class IntegratorImpl implements Integrator {
- private final Map<Class<?>, List<Method>> preCollectionChangeMethods;
- public IntegratorImpl() {
- this.preCollectionChangeMethods = new ConcurrentHashMap<>();
- }
- @Override
- public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
- EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
- registry.getEventListenerGroup(EventType.FLUSH_ENTITY).appendListener(new PreCollectionChangeFlushEntityEventListener());
- }
- private class PreCollectionChangeFlushEntityEventListener implements FlushEntityEventListener {
- @Override
- public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
- Object entity = event.getEntity();
- Class<?> entityClass = entity.getClass();
- if (!preCollectionChangeMethods.containsKey(entityClass)) {
- Method[] uniqueDeclaredMethods = ReflectionUtils.getUniqueDeclaredMethods(entityClass);
- List<Method> methods = Arrays.asList(uniqueDeclaredMethods).stream()
- .filter(method -> AnnotationUtils.findAnnotation(method, PreCollectionChange.class) != null)
- .map(method -> {
- method.setAccessible(true);
- return method;
- })
- .collect(Collectors.toList());
- // Place leaf methods in the end to correspond to constructors order.
- Collections.reverse(methods);
- preCollectionChangeMethods.put(entityClass, methods);
- }
- List<Method> methods = preCollectionChangeMethods.get(entityClass);
- for (Method method : methods) {
- try {
- method.invoke(entity, (Object[]) null);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new CallbackException(e);
- }
- }
- }
- }
- }
- @Entity
- public abstract class Device {
- @ManyToMany
- @JoinTable(
- name = "device_application",
- joinColumns = {
- @JoinColumn(name = "device_id"),
- },
- inverseJoinColumns = {
- @JoinColumn(name = "application_id"),
- })
- private Set<Application> applications = new HashSet<>();
- public Set<Application> getApplications() {
- return applications;
- }
- public void setApplications(Set<Application> applications) {
- this.applications = applications;
- }
- @PrePersist
- private void prePersist() {
- checkApplications();
- }
- @PreUpdate
- private void preUpdate() {
- checkApplications();
- }
- @PreCollectionChange
- private void checkApplications() {
- Class<? extends Application> applicationClass = getApplicationClass();
- for (Application application : applications) {
- if (!applicationClass.isAssignableFrom(application.getClass())) {
- throw new IllegalStateException("All applications must be of class " + applicationClass.getName());
- }
- }
- }
- @Transient
- protected abstract Class<? extends Application> getApplicationClass();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement