class HibernateJakartaPlugin
{
    private static final String ENTITY_ANNOTATION = "jakarta.persistence.Entity";
    private static AgentLogger LOGGER = AgentLogger.getLogger(HibernateJakartaPlugin.class);

    @Init
    Scheduler scheduler;

    @Init
    ClassLoader appClassLoader;

    Set<Object> regAnnotatedMetaDataProviders = Collections.newSetFromMap(new WeakHashMap<Object, Boolean>());

    Map<Object, String> regBeanMetaDataManagersMap = new WeakHashMap<Object, String>();

    // refresh commands
    Command reloadEntityManagerFactoryCommand =
            new ReflectionCommand(this, HibernateRefreshCommands.class.getName(), "reloadEntityManagerFactory");
    Command reloadSessionFactoryCommand =
            new ReflectionCommand(this, HibernateRefreshCommands.class.getName(), "reloadSessionFactory");

    private Command invalidateHibernateValidatorCaches = new Command() {
        @Override
        public void executeCommand() {
            LOGGER.debug("Refreshing BeanMetaDataManagerCache/AnnotatedMetaDataProvider cache.");

            try {
                Method resetCacheMethod1 = resolveClass("org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider").getDeclaredMethod("$$ha$resetCache");
                for (Object regAnnotatedDataManager : regAnnotatedMetaDataProviders) {
                    LOGGER.debug("Invoking org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.$$ha$resetCache on {}", regAnnotatedDataManager);
                    resetCacheMethod1.invoke(regAnnotatedDataManager);
                }
                for (Map.Entry<Object, String> entry : regBeanMetaDataManagersMap.entrySet()) {
                    LOGGER.debug("Invoking " + entry.getValue() + " .$$ha$resetCache on {}", entry.getKey());
                    Method resetCacheMethod2 = resolveClass(entry.getValue()).getDeclaredMethod("$$ha$resetCache");
                    resetCacheMethod2.invoke(entry.getKey());
                }
            } catch (Exception e) {
                LOGGER.error("Error refreshing BeanMetaDataManagerCache/AnnotatedMetaDataProvider cache.", e);
            }
        }
    };

    // is EJB3 or plain hibernate
    boolean hibernateEjb;

    /**
     * Plugin initialization properties (from HibernatePersistenceHelper or SessionFactoryProxy)
     */
    public void init(String version, Boolean hibernateEjb) {
        LOGGER.info("Hibernate plugin initialized - Hibernate Core version '{}'", version);
        this.hibernateEjb = hibernateEjb;
    }

    /**
     * Reload after entity class change. It covers also @Entity annotation removal.
     */
    @OnClassLoadEvent(classNameRegexp = ".*", events = LoadEvent.REDEFINE)
    public void entityReload(CtClass clazz, Class original) {
        // TODO list of entity/resource files is known to hibernate, better to check this list
        if (AnnotationHelper.hasAnnotation(original, ENTITY_ANNOTATION)
                || AnnotationHelper.hasAnnotation(clazz, ENTITY_ANNOTATION)
                ) {
            LOGGER.debug("Entity reload class {}, original classloader {}", clazz.getName(), original.getClassLoader());
            refresh(100);
        }
    }

    /**
     * New entity class - not covered by reloading mechanism.
     * <p/>
     * Increase the reload timeout to avoid duplicate reloading in case of recompile with IDE
     * and delete/create event sequence - than create is cached by this event and hotswap for
     * the same class by entityReload.
     */
    @OnClassFileEvent(classNameRegexp = ".*", events = {FileEvent.CREATE})
    public void newEntity(CtClass clazz) throws Exception {
        if (AnnotationHelper.hasAnnotation(clazz, ENTITY_ANNOTATION)) {
            refresh(500);
        }
    }

    @OnClassLoadEvent(classNameRegexp = ".*", events = LoadEvent.REDEFINE)
    public void invalidateClassCache() throws Exception {
        if (!regBeanMetaDataManagersMap.isEmpty() || !regAnnotatedMetaDataProviders.isEmpty()) {
            scheduler.scheduleCommand(invalidateHibernateValidatorCaches);
        }
    }

    // reload the configuration - schedule a command to run in the application classloader and merge
    // duplicate commands.
    private void refresh(int timeout) {<FILL_FUNCTION_BODY>}

    public void registerAnnotationMetaDataProvider(Object annotatedMetaDataProvider) {
        regAnnotatedMetaDataProviders.add(annotatedMetaDataProvider);
    }


    public void registerBeanMetaDataManager(Object beanMetaDataManager, String beanMetaDataManagerClassName) {
        regBeanMetaDataManagersMap.put(beanMetaDataManager, beanMetaDataManagerClassName);
    }

    private Class<?> resolveClass(String name) throws ClassNotFoundException {
        return Class.forName(name, true, appClassLoader);
    }

}

        if (hibernateEjb) {
            scheduler.scheduleCommand(reloadEntityManagerFactoryCommand, timeout);
        } else {
            scheduler.scheduleCommand(reloadSessionFactoryCommand, timeout);
        }
    
<no_super_class>