java - JPA 中两个表的 "Object comparisons can only be used with OneToOneMappings"

标签 java mysql jpa netbeans entity

我在 Mysql sensorlist 和 sensor_tags 中有两个表,Sensorlist 将激活来自传感器的寄存器(传感器的数据和用于识别传感器的 slID)。 Sensor_tags 将具有所有传感器的标签(来自 Activity 或非 Activity 的传感器)。此外,sensorlist 可能有一个标签(或 slId)未在 Sensor_tags 表中声明。我正在尝试查找未在 sensor_tag 表中声明的传感器标签。我在 netbeans 中使用 Web 服务,但总是出现错误:

Advertencia:   EJB5184:A system exception occurred during an invocation on EJB       SensorlistFacadeREST, method: public java.util.List entities.service.SensorlistFacadeREST.createSensorList()
Advertencia:   javax.ejb.EJBException

Caused by: Exception [EclipseLink-6076] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.QueryException

Exception Description: Object comparisons can only be used with OneToOneMappings.  Other mapping comparisons must be done through query keys or direct attribute level comparisons.

Mapping: [org.eclipse.persistence.mappings.DirectToFieldMapping[slId-->sensorlist.slId]] 
Expression: [
Query Key slId
   Base entities.Sensorlist]

Query: ReportQuery(name="Sensorlist.CreateSensorList" referenceClass=Sensorlist jpql="SELECT sl.slId, sl.slName1, sl.slName2, sl.slName3, sl.slInsertTimestamp, sl.slGMTOffset, sl.slActualTimestamp, sl.slActualValue,  sl.slActualStatus FROM Sensorlist sl LEFT OUTER JOIN SensorTags st ON sl.slId = st.sensorId WHERE st.sensorId IS NULL")
at org.eclipse.persistence.exceptions.QueryException.unsupportedMappingForObjectComparison(QueryException.java:1164)

我的表:

(这个是用SQL写的:)

TABLE`sensorlist` (
  `slId` INT(11) NOT NULL AUTO_INCREMENT,
  `slName1` VARCHAR(255) NULL DEFAULT NULL,
  `slName2` VARCHAR(255) NULL DEFAULT NULL,
  `slName3` VARCHAR(255) NULL DEFAULT NULL,
  `slInsertTimestamp` DATETIME NULL DEFAULT NULL,
  `slActualTimestamp` DATETIME NULL DEFAULT NULL,
  `slGMTOffset` INT(11) NULL DEFAULT NULL,
  `slActualValue` DOUBLE NULL DEFAULT NULL,
  `slActualStatus` INT(11) NULL DEFAULT NULL,
  INDEX `sensorlist_status_idx` (`slActualStatus` ASC),
  PRIMARY KEY (`slId`),
  CONSTRAINT `sensorlist_status`
    FOREIGN KEY (`slActualStatus`)
    REFERENCES `factoryecomation_v2`.`status` (`stId`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 21
DEFAULT CHARACTER SET = utf8;

TABLE `sensor_tags` (
  `sensor_tag` VARCHAR(45) NOT NULL,
  `id_sensor_catalog` INT(11) NULL DEFAULT NULL,
  `comm_device_tag` VARCHAR(45) NOT NULL,
  `max_value` FLOAT NULL DEFAULT NULL,
  `min_value` FLOAT NULL DEFAULT NULL,
  `id_measurement_unit` INT(11) NULL DEFAULT NULL,
  `sensor_id` INT(11) NULL DEFAULT NULL,
  `active` BIT(1) NOT NULL DEFAULT b'1',
  `insert_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_update_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`sensor_tag`),
  INDEX `fk_sensor_tags_sensorlist1_idx` (`sensor_id` ASC),
  CONSTRAINT `fk_sensor_tags_sensorlist1`
    FOREIGN KEY (`sensor_id`)
    REFERENCES `factory`.`sensorlist` (`slId`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

我使用 Netbeans 从数据库生成了 Restful Web 服务。从 SensorlistFacadeREST.java 我实现了一个 GET 方法:

@GET
@Path("operation/createSensorList")
@Produces({"application/xml", "application/json"})
public List<Sensorlist> createSensorList(){
     System.out.print("Prueba 1");
    Query query = em.createNamedQuery("Sensorlist.CreateSensorList");
    System.out.print("Prueba 2");
    List<Sensorlist> services = query.getResultList();
    System.out.print("Prueba 3");    
return services;
}

在 Sensorlist.java 中,我编写了查询,其目标是连接表 sensorlist 和 sensortags 以查找所有传感器的标签不退出。注意:如果我使用 st.sensor_id,我将收到错误消息“状态字段路径‘st.sensor_id’无法解析为有效类型”

@NamedQuery(name = "Sensorlist.CreateSensorList", query ="SELECT sl.slId, sl.slName1, sl.slName2, sl.slName3, sl.slInsertTimestamp, sl.slGMTOffset, sl.slActualTimestamp, sl.slActualValue,  sl.slActualStatus FROM Sensorlist sl LEFT OUTER JOIN SensorTags st ON sl.slId = st.sensorId WHERE st.sensorId IS NULL")

这是我的 Sensorlist.java(用于检查声明和变量):

//imports
@Entity
@Table(name = "sensorlist")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Sensorlist.findAll", query = "SELECT s FROM Sensorlist s"),
@NamedQuery(name = "Sensorlist.findBySlId", query = "SELECT s FROM Sensorlist s WHERE s.slId = :slId"),
@NamedQuery(name = "Sensorlist.findBySlName1", query = "SELECT s FROM Sensorlist s WHERE s.slName1 = :slName1"),
@NamedQuery(name = "Sensorlist.findBySlName2", query = "SELECT s FROM Sensorlist s WHERE s.slName2 = :slName2"),
@NamedQuery(name = "Sensorlist.findBySlName3", query = "SELECT s FROM Sensorlist s WHERE s.slName3 = :slName3"),
@NamedQuery(name = "Sensorlist.findBySlInsertTimestamp", query = "SELECT s FROM Sensorlist s WHERE s.slInsertTimestamp = :slInsertTimestamp"),
@NamedQuery(name = "Sensorlist.findBySlActualTimestamp", query = "SELECT s FROM Sensorlist s WHERE s.slActualTimestamp = :slActualTimestamp"),
@NamedQuery(name = "Sensorlist.findBySlGMTOffset", query = "SELECT s FROM Sensorlist s WHERE s.slGMTOffset = :slGMTOffset"),
@NamedQuery(name = "Sensorlist.findBySlActualValue", query = "SELECT s FROM Sensorlist s WHERE s.slActualValue = :slActualValue"),
@NamedQuery(name = "Sensorlist.CreateSensorList", query ="SELECT sl.slId, sl.slName1, sl.slName2, sl.slName3, sl.slInsertTimestamp, sl.slGMTOffset, sl.slActualTimestamp, sl.slActualValue,  sl.slActualStatus FROM Sensorlist sl LEFT OUTER JOIN SensorTags st ON sl.slId = st.sensorId WHERE st.sensorId IS NULL")})
public class Sensorlist implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "slId")
private Integer slId;
@Size(max = 255)
@Column(name = "slName1")
private String slName1;
@Size(max = 255)
@Column(name = "slName2")
private String slName2;
@Size(max = 255)
@Column(name = "slName3")
private String slName3;
@Column(name = "slInsertTimestamp")
@Temporal(TemporalType.TIMESTAMP)
private Date slInsertTimestamp;
@Column(name = "slActualTimestamp")
@Temporal(TemporalType.TIMESTAMP)
private Date slActualTimestamp;
@Column(name = "slGMTOffset")
private Integer slGMTOffset;
// @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Column(name = "slActualValue")
private Double slActualValue;
@OneToMany(mappedBy = "saSensorId")
private Collection<Sensorarchive> sensorarchiveCollection;
@OneToMany(mappedBy = "sensorId")
private Collection<SensorTags> sensorTagsCollection;
@JoinColumn(name = "slActualStatus", referencedColumnName = "stId")
@ManyToOne
private Status slActualStatus;
//more stuffs
}

最佳答案

如果关系已经在实体对象上定义,则不要使用 ON 运算符,或者至少为自定义 ON 过滤器放置 ON 子句。 ORM 已经知道两个实体如何使用关联的映射链接在一起,所以语法上正确的查询是

select sl from Sensorlist sl // why select each and every field instead of selecting the entity?
left outer join sl.sensorTagsCollection st
where st.sensorId is null

我不确定我是否理解您要通过此查询实现的目标如果目标是找到没有标签的 SensorList,则查询应该是

select sl from Sensorlist sl where sl.sensorTagsCollection is empty

旁注:你真的应该修正你的命名。你不会说“你好,先生,你叫什么名字?”。那么为什么要说 sensorList.getSlName() 而不是简单地 sensorList.getName()

关于java - JPA 中两个表的 "Object comparisons can only be used with OneToOneMappings",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24344842/

相关文章:

mysql - 如何将特定数字连接到所有行的特定列的现有值

java - 有没有办法扫描 JPA 实体而不在 persistence.xml 文件中声明持久类?

java - JPA 可以在删除子对象时处理删除父对象吗?

java - Android Studio : SuperpoweredAdvancedAudioPlayer. h: 没有那个文件或目录

java - 正确使用 fragment 中的实例状态保存

mysql - 将表a中的值和表b中的id插入到表c中

unit-testing - 如何测试 Spring Data 存储库?

java - 使用 HashMap 的稀疏数组

java - 如何替换已弃用的方法 Date.setHours(int)?

php - 使用数据透视表 mySQL 查询特定值