Атрибуты первичного ключа статической метамодели не заполнены (NullPointerException) - PullRequest
0 голосов
/ 06 июня 2018

Я написал мыльные сервисы, в которых данные читаются из базы данных через спящий режим.Я использовал запросы JPA Criteria и статическую метамодель JPA в запросах для получения данных.Я генерирую метамодель с помощью плагина hibernate-jpamodelgen.При обработке запроса, когда служба создает запрос на чтение данных из базы данных, тогда SingularAttributes первичных ключей в классах статической модели JPA равны нулю (я не знаю, почему они не заполняются, хотя заполняются другие атрибуты, которые не являются первичными ключами), и этогенерирует исключение NullPointerException.

Мои классы:

@MappedSuperclass
public abstract class ReadModel implements  Serializable, Cloneable {

  public ReadModel() {
  }

  @Column(name = "customerId")
  private BigInteger customerId;

  @Id
  @Column(name = "device_id")
  private BigInteger deviceId;

  @Column(name = "date")
  private Date date;

  @Column(name = "time")
  private Time time;

  @Id
  @Column(name = "device_time")
  private Timestamp deviceTime;


  public BigInteger getCustomerId() {
    return customerId;
  }

  public ReadModel setCustomerId(BigInteger customerId) {
    this.customerId = customerId;
    return this;
  }

  public BigInteger getId() {
    return deviceId;
  }

  public ReadModel setId(BigInteger deviceId) {
    this.deviceId = deviceId;
    return this;
  }

  public Date getDate() {
    return date;
  }

  public ReadModel setDate(Date date) {
    this.date = date;
    return this;
  }

  public Time getTime() {
    return time;
  }

  public ReadModel setTime(Time time) {
    this.time = time;
    return this;
  }

  public Timestamp getDeviceTime() {
    return deviceTime;
  }

  public ReadModel setDeviceTime(Timestamp deviceTime) {
    this.deviceTime = deviceTime;
    return this;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ReadModel that = (ReadModel) o;
    return Objects.equals(getId(), that.getId()) &&
        Objects.equals(getDeviceTime(), that.getDeviceTime());
  }

  @Override
  public int hashCode() {

    return Objects.hash(getId(), getDeviceTime());
  }
}

И второй класс:

@Entity
@Table(name = "device_data")
public class DeviceData extends ReadModel implements  Serializable,Cloneable {
  public DeviceDataRead() {

  }
}

И соответствующие сгенерированные метамодели JPA-статики:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(ReadModel.class)
public abstract class ReadModel_  {

    public static volatile SingularAttribute<ReadModel, Time> time;
    public static volatile SingularAttribute<ReadModel, BigInteger> customerId;
    public static volatile SingularAttribute<ReadModel, BigInteger> deviceId;
    public static volatile SingularAttribute<ReadModel, Timestamp> deviceTime;
    public static volatile SingularAttribute<ReadModel, Date> date;

    public static final String TIME = "time";
    public static final String CUSTOMER_ID = "customerId";
    public static final String DEVICE_ID = "deviceId";
    public static final String DEVICE_TIME = "deviceTime";
    public static final String DATE = "date";

} 

И

@StaticMetamodel(DeviceData.class)
public abstract class DeviceData_ extends ReadModel_ {
    public DeviceData_() {
    }
}

Мои зависимости hibernare:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>${hibernate.version}</version>
</dependency>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-jpamodelgen</artifactId>
  <version>${hibernate.version}</version>
  <scope>provided</scope>
</dependency>

<properties> 
    <hibernate.version>5.3.1.Final</hibernate.version>
</properties>

И вот мои служебные методы: функция createProperties () возвращает свойства Object.

public class HibernateUtils {
      private static SessionFactory factory = null;

      public static SessionFactory getSessionFactory(){
        if (factory == null) {
          factory = buildSessionFactoryFromAnnotatedClasses(HOST, PORT, DB_NAME, PROTOCOL_MY_SQL,
              USER_NAME, PASSWORD, CONNECTION_MIN_POOL_SIZE_FOR_PARTICULAR_CLASS_VALUE,
              CONNECTION_MAX_POOL_SIZE_FOR_PARTICULAR_CLASS_VALUE, Arrays.asList(DeviceData););
        }
        return factory;
      }

      public static SessionFactory buildSessionFactoryFromAnnotatedClasses(String host,
          Integer port, String dbName, String protocol, String userName, String password,
          Integer minPoolSize, Integer maxPoolSize, List<Class> annotatedClassNames) {
        StandardServiceRegistry standardRegistry =
            new StandardServiceRegistryBuilder().applySettings(createProperties(
                host, port, dbName, protocol, userName, password, minPoolSize, maxPoolSize)
                .getProperties()).build();

        MetadataSources sources = new MetadataSources(standardRegistry);
        annotatedClassNames.forEach(sources::addAnnotatedClass);
        Metadata metaData = sources.getMetadataBuilder().build();
        return metaData.getSessionFactoryBuilder().build();
      }
  }

И вот запрос:

ReadModel_.deviceId и ReadModel_.deviceTime оба имеют нулевое значение, но все остальные атрибуты заполнены (ReadModel_.CUSTOMER_ID, ReadModel_.DATE, ReadModel_.TIME не являются нулевыми)

try (Session session = HibernateUtils.getSessionFactory().openSession()) {
        SingularAttribute<ReadModel, BigInteger> deviceId = ReadModel_.deviceId;//this is null
        SingularAttribute<ReadModel, Timestamp> devicetime = ReadModel_.deviceTime;//this is null
        CriteriaBuilder cb = session.getCriteriaBuilder();
        CriteriaQuery<DeviceData> cq = cb.createQuery(DeviceData.class);
        Root<DeviceData> root = cq.from(DeviceData.class);
        List<Predicate> conditions = new ArrayList<>();
        conditions.add(cb.isTrue(root.get(deviceId).in(devicList)));//root.get(deviceId) throws NullPointerException
        conditions.add(cb.greaterThanOrEqualTo(root.get(devicetime), dataStartTime()));

        cq.where(conditions.toArray(new Predicate[]{})).orderBy(cb.asc(root.get(devicetime)));
        Query query= session.createQuery(cq);

    }

Я застрял очень плохо.Может кто-нибудь сказать мне, что я должен делать?заранее спасибо.

1 Ответ

0 голосов
/ 06 июня 2018

Попробуйте использовать @EmbeddedId для составного ключа

Пример руководства

...