2013-11-02 4 views
0

Query1 (Работает отлично !!!):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

что такое переменная 'start'? Почему вы не вызываете метод getX() во втором примере? – fracz

+0

«start» - это пример класса местоположения, полученного из HTTP POST-данных ... Например. такие же, как Location start = new Location ("1.0", "1.0"); ... Я не использую getx(), поскольку хочу проверить равенство сложных объектов ... –

ответ

0

Исключение TransientObjectException, когда класс, созданный с помощью конструктора, сравнивался с тем же объектом того же класса, который читается из базы данных. Поскольку Class Route аннотируется как @Entity, запрос считает, что первый объект является временным (поскольку он не имеет набора @id field).

1

Исключение не имеет много общего с самого запроса.

Это заброшено, потому что перед выполнением запроса Hibernate сбрасывает изменения, которые еще не были сброшены. И не может этого сделать, потому что ... объект ссылается на несохраненный экземпляр переходного процесса. Поэтому перед выполнением запроса обязательно сохраните временные экземпляры.

+0

Ну, я вижу, что Route и его свойство start (как и все другие связанные объекты) сохраняются перед запуском запроса ... поэтому я не вижу, что может быть, вероятно, это временный экземпляр. –

+0

Пройдите код, используя отладчик, и попробуйте отследить все сущности, которые прикреплены к управляемому, но не выполняются постоянно, прежде чем выполнять запрос. –

+0

Перед выполнением запроса у меня осталось только одно сущность: «Пользователь», у пользователя есть 1 маршрут, а в маршруте есть начало и конец местоположения. Когда я вызываю em.getTransaction(). Commit(); Я вижу их все в базе данных. Если я попытаюсь вызвать em.flush, jboss скажет мне, что активных транзакций нет. Поэтому я могу вызвать em.close(). А позже создайте новый EntityManager для запуска соответствующего запроса. У меня есть подозрение, что, возможно, ошибка связана с местоположением, на которое ссылается «start» (класс Location), который получен из HTTP POST-данных и имеет id = null. Но я чувствую, что эта теория немного далека. –

Смежные вопросы