通过Hibernate Annotation和JPA条件在一个公共列的基础上连接两个表查询无法正常工作

时间:2019-01-07 09:44:18

标签: java hibernate hibernate-annotations jpa-criteria

我有两个表device_datadevice_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());
  }
}

我编写了一个Query来从这两个表的连接中获取数据。

  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。因此,这是休眠生成的查询。

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工作台上运行此查询时,它将正常工作并给我结果。但是冬眠不断给我一个例外,我不知道为什么?

例外

  

java.lang.ClassCastException:com.sbi.model.DeviceConnection无法转换为java.math.BigInteger

0 个答案:

没有答案