2013-11-02 35 views
0

查询1(工作正常!):JPA JPQL查询,其中object1 = Object2的

em.createQuery(
      "SELECT r FROM Route r WHERE r.start.x = :x" 
      , Route.class).setParameter("x", start.getX()) 

QUERY2(ID真的很喜欢这个工作!):

em.createQuery(
      "SELECT r FROM Route r WHERE r.start = :x" 
      , Route.class).setParameter("x", start) 
      .setMaxResults(20) 

抛出: TransientObjectException :对象引用未保存的瞬态实例 - 在冲刷前保存瞬态实例

路由实体:

@Entity 
@XmlRootElement(name="route") 

@XmlAccessorType(XmlAccessType.NONE) 
public class Route { 
private Long id; 
private User user; 
private Location start; 
private Location finish; 

public Route() { 
} 

@Id 
@GeneratedValue 
public Long getId() { 
    return id; 
} 

public void setId(Long id) { 
    this.id = id; 
} 

@ManyToOne 
@JoinColumn 
public User getUser() { 
    return user; 
} 

public void setUser(User user) { 
    this.user = user; 
} 

@OneToOne(cascade=CascadeType.PERSIST) 
public Location getStart() { 
    return start; 
} 

public void setStart(Location start) { 
    this.start = start; 
} 

@OneToOne(cascade=CascadeType.PERSIST) 
public Location getFinish() { 
    return finish; 
} 

public void setFinish(Location finish) { 
    this.finish = finish; 
} 

}

地点:

@Entity 
public class Location { 

@Id 
@GeneratedValue 
private Long id; 

private double x; 

private double y; 

public Location() { 
} 

public Location(double x, double y) { 
    this.x = x; 
    this.y = y; 
} 

@XmlTransient 
public double getX() { 
    return x; 
} 

public void setX(double x) { 
    this.x = x; 
} 

public double getY() { 
    return y; 
} 

public void setY(double y) { 
    this.y = y; 
} 

public boolean equals(Object o) { 
    if ((o instanceof Location) 
      && (((Location)o).getX() == this.x) 
      && (((Location)o).getY() == this.y)) 
    { 
     return true; 
    } 
    else return false; 
} 

}

+0

什么是“开始”变量?你为什么不在第二个例子中调用'getX()'方法? – fracz

+0

“开始”是从HTTP POST数据收到的位置类实例...例如。与Location start = new Location(“1.0”,“1.0”)相同; ...我没有使用getx(),因为我想能够测试复杂对象的相等性...... –

回答

0

TransientObjectException被抛出。由于Class Route被标注为@Entity,因此查询已将第一个对象视为临时对象(因为它没有设置@id字段)。

1

异常没有太多做的查询本身。

它抛出,因为执行查询之前,Hibernate的刷新都没有被刷新尚未改变。并且不能这样做,因为...对象引用未保存的瞬态实例。因此,请确保在执行查询之前保存瞬态实例。时所通过的构造实例化类正在从数据库读出的同一类的同一对象进行比较

+0

嗯,我可以看到Route,它的开始属性(以及所有其他相关实体)被持久化数据库在运行查询之前...所以我没有看到可能是那个瞬态实例。 –

+0

使用调试器逐句通过代码,并尝试跟踪所有连接到受管理的实体但在执行查询之前不会执行持久化的实体。 –

+0

在运行查询之前,我只有一个实体持久化:“用户”,用户有1个路由,路由有一个开始和结束位置。一旦我调用em.getTransaction()。commit();我可以在数据库中看到他们全部。如果我尝试调用em.flush,jboss会告诉我没有活动事务。所以我可以调用em.close()。稍后创建新的EntityManager以运行有问题的查询。我怀疑可能错误是由于由“POST”数据收到的“start”(Location类)引用的Location,并且id = null。但我觉得这个理论有点牵强。 –