Ссылки на метамодели Hibernate обнуляются через некоторое время после развертывания - PullRequest
0 голосов
/ 30 ноября 2018

У меня странная ситуация с использованием метамоделей Hibernate / JPA.Наше зрелое веб-приложение Wicket 7 работает нормально, но через некоторое время некоторые значения полей метамодели становятся равными нулю.Это всегда один и тот же преступник (в приложении несколько сотен сущностей, и он всегда один).Генератор метамодели создает это для класса ProductGroup:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(ProductGroup.class)
public abstract class ProductGroup_ extends com.sw.generic.data.AbstractBusinessEntity_ {

    public static volatile SingularAttribute<ProductGroup, String> serviceLevelDescription;
    public static volatile SingularAttribute<ProductGroup, String> supportDescription;
    public static volatile SingularAttribute<ProductGroup, String> code;
    public static volatile SingularAttribute<ProductGroup, Boolean> useProductSubgroupL2;
    public static volatile SingularAttribute<ProductGroup, String> description;
    public static volatile SingularAttribute<ProductGroup, Boolean> useSupportSubgroupL2;
    public static volatile SingularAttribute<ProductGroup, String> productSubgroupLevel1Description;
    public static volatile SingularAttribute<ProductGroup, String> serviceLevelGroupDescription;
    public static volatile SingularAttribute<ProductGroup, String> productSubgroupLevel2Description;
    public static volatile SingularAttribute<ProductGroup, String> supportSubgroupLevel1Description;
    public static volatile SingularAttribute<ProductGroup, String> supportSubgroupLevel2Description;

}

Место, где мы получаем нулевые указатели, - это перечисление, которое сохраняет атрибут в виде поля:

public class DefaultProductGroupEntityDescriptionLabel extends OptionalLabel {

  private static final long serialVersionUID = 1L;

  public static enum ProductGroupEntityType {
    SUPPORT_SERVICE( "product.group.label.support.default", ProductGroup_.supportDescription ),
    SUPPORT_SUBGROUP_L1( "product.group.label.support.subgroup.l1.default", ProductGroup_.supportSubgroupLevel1Description ),
    SUPPORT_SUBGROUP_L2( "product.group.label.support.subgroup.l2.default", ProductGroup_.supportSubgroupLevel2Description ),
    PRODUCT_SUBGROUP_L1( "product.group.label.product.subgroup.l1.default", ProductGroup_.productSubgroupLevel1Description ),
    PRODUCT_SUBGROUP_L2( "product.group.label.product.subgroup.l2.default", ProductGroup_.productSubgroupLevel2Description ),
    SERVICE_LEVEL( "product.group.label.servicelevel.default", ProductGroup_.serviceLevelDescription ),
    SERVICE_LEVEL_TYPE( "product.group.label.serviceleveltype.default", ProductGroup_.serviceLevelGroupDescription );

    private String m_singularKey;
    private String m_pluralKey;

    private Attribute<ProductGroup,String> m_attribute;

    private ProductGroupEntityType( String p_key, Attribute<ProductGroup,String> p_attribute ) {
      this( p_key, p_key, p_attribute );
    }

    private ProductGroupEntityType( String p_singularKey, String p_pluralKey, Attribute<ProductGroup,String> p_attribute ) {
      m_singularKey = p_singularKey;
      m_pluralKey = p_pluralKey;
      m_attribute = p_attribute;
    }

    public String getSingularKey() {
      return m_singularKey;
    }
    public String getPluralKey() {
      return m_pluralKey;
    }

    public Attribute<ProductGroup,String> getAttribute() {
      return m_attribute;
    }

    public String getDescription( ProductGroup p_group ) {
      try {
        return BeanUtils.getSimpleProperty( p_group, getAttribute().getName() ); // <-- This is where the NPE occurs!
      } catch( Exception e_e ) {
        throw new IllegalStateException( name() + " has a bad property setting - cannot get Vendor property " + getAttribute().getName(), e_e );
      }
    }
  }

  protected IModel<ProductGroupEntityType> m_typeModel;

  protected IModel<String> m_baseModel;

  /**
   * @param p_id
   */
  public DefaultProductGroupEntityDescriptionLabel( String p_id, ProductGroupEntityType p_type ) {
    this( p_id, Model.of( p_type ) );
  }

  /**
   * @param p_id
   */
  public DefaultProductGroupEntityDescriptionLabel( String p_id, IModel<ProductGroupEntityType> p_typeModel ) {
    super( p_id );
    m_typeModel = p_typeModel;
  }

  @Override
  public void detachModels() {
    super.detachModels();
    m_typeModel.detach();
    m_baseModel.detach();
  }

  protected void onInitialize() {
    super.onInitialize();

    m_baseModel = createBaseModel();

    setDefaultModel( createDescriptionModel( m_baseModel ) );

    add( new MultilineTooltipBehavior( new LoadableDetachableModel<String>() {

      private static final long serialVersionUID = 1L;

      @Override
      protected String load() {
        return getString( m_typeModel.getObject().getSingularKey() );
      }
    } ) );
  }

  @Override
  protected void onDetach() {
    super.onDetach();
    if( m_baseModel != null ) {
      m_baseModel.detach();
    }
  }

  /**
   * Creates the base model for getting the description
   * @return a model for getting the description.  This version gets the default description from the property settings.
   */
  protected IModel<String> createBaseModel() {
    return new LoadableDetachableModel<String>() {

      private static final long serialVersionUID = 1L;

      @Override
      protected String load() {
        return getString( isPlural() ? m_typeModel.getObject().getPluralKey() : m_typeModel.getObject().getSingularKey() );
      }
    };
  }

  /**
   * Allows subclasses to return a modified version of the model, so the base description can be part of a more complex description.
   * @param p_baseDescriptionModel
   * @return the base model unchanged by default
   */
  protected IModel<String> createDescriptionModel( IModel<String> p_baseDescriptionModel ) {
    return p_baseDescriptionModel;
  }

  /**
   * If true, plural versions of the key will be used.
   * @return false by default.
   */
  public boolean isPlural() {
    return false;
  }
}

Вызов ProductGroupEntityType ::getDescription вызывает ошибку, но не при первоначальном развертывании, а спустя несколько часов:

Caused by: java.lang.NullPointerException
    at com.sw.system4.ui.product.group.DefaultProductGroupEntityDescriptionLabel$ProductGroupEntityType.getDescription(DefaultProductGroupEntityDescriptionLabel.java:64)
    at com.sw.system4.ui.product.group.ProductGroupEntityDescriptionModel.load(ProductGroupEntityDescriptionModel.java:57)
    at com.sw.system4.ui.product.group.ProductGroupEntityDescriptionModel.load(ProductGroupEntityDescriptionModel.java:17)
    at org.apache.wicket.model.LoadableDetachableModel.getObject(LoadableDetachableModel.java:135)
    at org.apache.wicket.model.StringResourceModel.getString(StringResourceModel.java:454)
    at org.apache.wicket.model.StringResourceModel$AssignmentWrapper.load(StringResourceModel.java:271)

Этот код используется постоянно и в основном не вызывает этой проблемы.

Остановка иперезапуск сервера Tomcat, на котором он работает, заставляет его работать снова.

Я подозреваю, что если я изменю поле атрибута ProductGroupEntityType с Attribute на String, а затем передам в attribute.getName (), так что это не приведет к сохранениюСсылка, которая бы исправить вещи, но может ли кто-нибудь сказать мне, почему это происходит в первую очередь?Заранее спасибо.

Hibernate 5.1.14, Java 8

...