Соедините две таблицы на основе одного общего столбца с помощью аннотации Hibernate и критериев JPA. Запрос не работает должным образом - PullRequest
0 голосов
/ 07 января 2019

У меня есть две таблицы device_data и device_connection. Я хочу объединить эти две таблицы на основе столбца customerId. Обе таблицы имеют столбец customerId.

DeviceData

import java.io.Serializable;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

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

  @Id
  @Column(name = "identifier")
  private BigInteger identifier;

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

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

  @Column(name = "signal_strength")
  private Double signalStrength;

  @OneToOne
  @JoinColumn(name = "ctr_id", nullable = false, insertable = false, updatable = false, referencedColumnName = "ctr_id")
  private DeviceConnection deviceConnection;


  public BigInteger getIdentifier() {
    return identifier;
  }

  public DeviceData setIdentifier(BigInteger identifier) {
    this.identifier = identifier;
    return this;
  }

  public Timestamp getDeviceTime() {
    return deviceTime;
  }

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

  public BigInteger getCustomerId() {
    return customerId;
  }

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

  public DeviceConnection getDeviceConnection() {
    return deviceConnection;
  }

  public DeviceData setDeviceConnection(
      DeviceConnection deviceConnection) {
    this.deviceConnection = deviceConnection;
    return this;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    DeviceData that = (DeviceData) o;
    return identifier.equals(that.identifier) &&
        deviceTime.equals(that.deviceTime);
  }

  @Override
  public int hashCode() {
    return Objects.hash(identifier, deviceTime);
  }
}

DeviceConnection

import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "device_connection")
public class DeviceConnection implements Serializable , Cloneable {

  public DeviceConnection() {
  }

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

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

  @Column(name = "low_signal_strength_limit")
  private Integer lowSignalStrengthLimit;

  public BigInteger getCustomerId() {
    return customerId;
  }

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

  public Integer getLowSignalStrengthLimit() {
    return lowSignalStrengthLimit;
  }

  public DeviceConnection setLowSignalStrengthLimit(
      Integer lowSignalStrengthLimit) {
    this.lowSignalStrengthLimit = lowSignalStrengthLimit;
    return this;
  }

  public BigInteger getId() {
    return id;
  }

  public DeviceConnection setId(BigInteger id) {
    this.id = id;
    return this;
  }

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

  @Override
  public int hashCode() {

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

Я написал запрос для получения данных из объединения этих двух таблиц.

  CriteriaBuilder cb = session.getCriteriaBuilder();
    CriteriaQuery<DeviceData> cq = cb.createQuery(DeviceData.class);
    Root<DeviceData> root = cq.from(DeviceData.class);
    Join<DeviceData, DeviceConnection> join = (Join<DeviceData, DeviceConnection>) root
            .fetch(DeviceData_.deviceConnection);
    List<Predicate> conditions = new ArrayList<>();
    conditions.add(cb.equal(root.get(DeviceData_.CUSTOMER_ID), join.get(
        DeviceConnection_.CUSTOMER_ID)));
    conditions.add(cb.greaterThanOrEqualTo(root.get(DeviceData_.DEVICE_TIME),
        config.getDataStartTime()));
    if (isNotNull(config.getDataEndTime())) {
      conditions.add(cb.lessThanOrEqualTo(root.get(DeviceData_.DEVICE_TIME),
          config.getDataEndTime()));
    }
    cq.where(conditions.toArray(new Predicate[]{}))
        .orderBy(cb.asc(root.get(DeviceData_.DEVICE_TIME)));
    return session.createQuery(cq);

И я установил для свойства SHOW_SQL значение TRUE. Итак, вот запрос, который генерирует hibernate.

select
    devicedata0_.occurrence_time as occurren1_3_0_, devicedata0_.identifier as identifier2_3_0_, connection1_.id as id1_0_1_, devicedata0_.ctr_id as ctr_id9_3_0_, devicedata0_.signal_strength as signal_15_3_0_, connection1_.ctr_id as ctr_id7_0_1_, connection1_.low_signal_strength_limit as low_sig14_0_1_ 
from 
    device_data devicedata0_ 
    inner join device_connection connection1_ on 
        devicedata0_.ctr_id=connection1_.ctr_id 
where 
    devicedata0_.ctr_id=connection1_.ctr_id and 
    devicedata0_.created_at>='2018-06-12 12:00:00' 
order by
    devicedata0_.created_at asc 
limit 2000;

когда я запускаю этот Запрос на My Sql workbench, он будет работать ожидаемым образом и даст мне результаты. Но спящий постоянно дает мне исключение, я не знаю почему?

Исключение

java.lang.ClassCastException: com.sbi.model.DeviceConnection не может быть приведен к java.math.BigInteger

...