"对象比较只能与OneToOneMappings"一起使用。对于JPA中的两个表

时间:2014-06-21 18:55:21

标签: java mysql jpa netbeans entity

我在Mysql sensorlist和sensor_tags中有两个表,Sensorlist将激活传感器的寄存器(传感器的数据和slID来识别传感器)。并且Sensor_tags将具有所有传感器的标签(来自传感器激活或未激活)。此外,sensorlist可能在Sensor_tags表中未声明标记(或slId)。我试图找到一个未在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中,我编写了Query,其目标是连接表sensorlist和sensortags,以查找所有Sensor的标签不会退出。注意:如果我使用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
}

1 个答案:

答案 0 :(得分:9)

如果已在实体对象上定义了关系,则不能使用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

旁注:你应该确定你的命名。你不能说&#34;先生,你的先生名字是什么?&#34;。那你为什么要说sensorList.getSlName()而不是简单sensorList.getName()