Каждый объект JPA должен иметь первичный ключ. Ваши объекты JPA могут неправильно отображать первичный ключ, если таковой имеется, в таблице базы данных.
Я столкнулся с той же проблемой. В моем классе модели у меня была только одна переменная класса, аннотированная с помощью @Id. Однако это не было точным отражением самой таблицы, которая имеет составной первичный ключ. Таким образом, мои результаты запроса вернули правильное количество строк, но каждый из них содержал одинаковые значения, хотя фактические данные были разными в db. Например, этот запрос:
Query query = entityManager.createQuery
("SELECT tbl FROM Tbl tbl WHERE tbl.id = 100
and tbl.code in ('A','B','C')");
... вернулся 10 строк, каждый из которых показывает код из 'A'. Но на самом деле 9 из этих 10 строк имели другое значение ('B' или 'C'). Казалось, что результаты были кешированы и/или предикат tbl.code был проигнорирован. (Это случилось, если я использовал JPQL или Собственный SQL.) Очень запутанно.
Чтобы это исправить, я добавил дополнительный @Id аннотации к моей модели, чтобы отразить составной первичный ключ:
@Id
@Column(name = "Code")
public String getCode() {
return this.code;
}
Теперь запрос возвращает данные правильно и кода выберите критерии больше не эффективно проигнорировано ,
Редакция: Несмотря на то, что вышеописанное работало для меня, при дальнейших исследованиях, кажется, лучший подход для настройки отдельного класса первичных ключей JPA Entity. См. http://docs.oracle.com/cd/E16439_01/doc.1013/e13981/cmp30cfg001.htm.
Например, вот класс Entity со встроенным первичным ключом (см @EmbeddedId):
/**
* The persistent class for the SOME_TABLE database table.
*/
@Entity
@Table(name = "SOME_TABLE")
public class SomeTable implements Serializable {
@EmbeddedId
private SomeTablePk id;
@Column(name = "NUMBER_HRS")
private BigDecimal numberHrs;
...
... и вот первичный ключ класса композит (см @Embeddable):
@Embeddable
public class SomeTablePk implements Serializable {
@Column(name = "SOME_ID")
private String someId;
@Column(name = "ANOTHER_ID")
private BigDecimal anotherId;
public String getSomeId() {
return someId;
}
...