Я создал именованный запрос, который выглядит следующим образом с отображением набора результатов:
@NamedNativeQueries({ @NamedNativeQuery(name = "Q_INSTRUMENTS", query = "SELECT i.ID, i.TICKER, i.ISIN, i.SEDOL, i.NAME, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID FROM INSTRUMENT i INNER JOIN COUNTRY c ON i.COUNTRY_ID = c.ID"
+ " GROUP BY i.ID, i.TICKER, i.ISIN, i.SEDOL, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID, c.NAME HAVING i.ID = MAX(i.ID) ORDER BY i.NAME, c.NAME ASC", resultClass = Instrument.class, resultSetMapping = "InstrumentMapping") })
@SqlResultSetMapping(name = "InstrumentMapping", entities = { @EntityResult(entityClass = Instrument.class, fields = {
@FieldResult(name = "id", column = "ID"), @FieldResult(name = "ticker", column = "TICKER"),
@FieldResult(name = "sedol", column = "SEDOL"), @FieldResult(name = "isin", column = "ISIN"),
@FieldResult(name = "name", column = "NAME"), @FieldResult(name = "countryId", column = "COUNTRY_ID"),
@FieldResult(name = "contractSize", column = "CONTRACT_SIZE"),
@FieldResult(name = "expiryDate", column = "EXPIRY_DATE"), @FieldResult(name = "typeId", column = "TYPE_ID") }) })
, и вот класс, который аннотируется этим именованным запросом
public class Instrument extends ManagedEntityBase{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 10)
private String ticker;
@Column(length = 30)
private String isin;
@Column(length = 10, unique = true, nullable = false)
private String sedol;
@Column(length = 60, nullable = false)
private String name;
@Column(name = "COUNTRY_ID", nullable = false, insertable = false, updatable = false)
private long countryId;
@Column(name = "TYPE_ID", nullable = false, insertable = false, updatable = false)
private byte typeId;
@Column(name = "CONTRACT_SIZE", nullable = false)
private Long contractSize;
@Transient
private String contractSizeString;
@Temporal(TemporalType.DATE)
@Column(name = "EXPIRY_DATE")
private Date expiryDate;
public Instrument() {
// Default constructor
this.contractSize = 1L;
}
ublic Instrument(String sedol, Country country, InstrumentType type) {
this();
this.sedol = sedol;
this.country = country;
this.type = type;
}
/**
* Creates an {@link Instrument} with the given sedol, isin, country and type.
*
* @param sedol instrument sedol
* @param isin instrument isin
* @param country instrument country
* @param name
* @param ticker
* @param type instrument type
*/
public Instrument(String sedol, String isin, Country country, String name, String ticker, InstrumentType type) {
this(sedol, country, type);
this.isin = isin;
this.name = name;
this.ticker = ticker;
}
}
Когда я попытаться вызвать запрос имени:
public static List<Instrument> getInstruments() {
return DatabaseUtility.getEntityManager().createNamedQuery("Q_INSTRUMENTS").getResultList();
}
Я получаю следующую ошибку:
[EL Warning]: 2020-01-31 15:55:40.732--UnitOfWork(1788318093)--Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [ArrayRecord(
=> 3000000002285
=> 00577
=> BMG8827A1045
=> BYX9N24
=> 13 HOLDINGS LTD, THE
=> 2
=> 1
=> null
=> 1)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReadAllQuery(name="Q_INSTRUMENTS" referenceClass=Instrument sql="SELECT i.ID, i.TICKER, i.ISIN, i.SEDOL, i.NAME, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID FROM INSTRUMENT i INNER JOIN COUNTRY c ON i.COUNTRY_ID = c.ID GROUP BY i.ID, i.TICKER, i.ISIN, i.SEDOL, i.COUNTRY_ID, i.CONTRACT_SIZE, i.EXPIRY_DATE, i.TYPE_ID, c.NAME HAVING i.ID = MAX(i.ID) ORDER BY i.NAME, c.NAME ASC")
В таблице expiry_date действительно пусто, но это не принимает участие из первичного ключа и по умолчанию значение NULL в случае истечения срока действия истина. Я использую EclipseLink с Postre SQL. Я пытаюсь перенести текущий код из старой Sybase в новую Postre SQL. С источником данных Sybase ошибка не происходит.
Я пытался использовать
<property name="eclipselink.jpa.uppercase-column-names" value="true"/>
, чтобы убедиться, что сопоставление столбцам не сделано неправильно, но это не устранило мою проблему