0

I have an entity Instrument with these fields:

@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(referencedColumnName = "instrumentId", nullable = false)
public Set<InstrumentSymbol> getSymbols() {
    return this.symbols;
}

@Column
@JsonProperty("statusCode")
public Integer getStatusCode() {
    return statusCode;
}

InstrumentSymbol has now a column in the database called symbold_instrumentId which Hibernate automatically creates but there is no property associated with it. How can I find all InstrumentSymbol where statusCode is 1?

I tried

    CriteriaBuilder builder = session.getCriteriaBuilder();
    CriteriaQuery<InstrumentSymbol> query = builder.createQuery(InstrumentSymbol.class);
    Root<InstrumentSymbol> rootSymbol = query.from(InstrumentSymbol.class);

    Subquery<Long> subquery = query.subquery(Long.class);
    Root<Instrument> rootInstrument = subquery.from(Instrument.class);
    subquery.select(rootInstrument.get(Instrument_.instrumentId));
    subquery.where(builder.equal(rootInstrument.get(Instrument_.statusCode), 1));

    query.where(builder.in(rootSymbol.get("symbols_instrumentId")).in(subquery)); // <--- Fails here

but that fails with

java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [symbols_instrumentId] on this ManagedType [....InstrumentSymbol]

Then I tried to add a custom field to my @StaticMetamodel:

public static volatile SingularAttribute<InstrumentSymbol, Long> symbols_instrumentId; // NOSONAR Hibernate 5 requires this

but unfortunately, Hibernate ignores it:

    // Hibernate fills these fields for me
    assertEquals("Instrument#instrumentId(BASIC)", Instrument_.instrumentId.toString());
    assertEquals("InstrumentSymbol#instrumentSymbolId(BASIC)", InstrumentSymbol_.instrumentSymbolId.toString());
    // But not this...
    assertEquals(null, InstrumentSymbol_.symbols_instrumentId);

How do I create a query which works?

For reference, this is the static meta data for InstrumentSymbol:

@StaticMetamodel(InstrumentSymbol.class)
public class InstrumentSymbol_ { // NOSONAR Hibernate 5 requires this
    public static volatile SingularAttribute<InstrumentSymbol, String> externalInstrumentSymbolId; // NOSONAR Hibernate 5 requires this
    public static volatile SingularAttribute<InstrumentSymbol, Long> instrumentSymbolId; // NOSONAR Hibernate 5 requires this
    public static volatile SingularAttribute<InstrumentSymbol, String> symbol; // NOSONAR Hibernate 5 requires this
    public static volatile SingularAttribute<InstrumentSymbol, String> symbolType; // NOSONAR Hibernate 5 requires this
}

(no column with the FK of Instrument). This is the auto generated DDL:

create table InstrumentSymbol (
    instrumentSymbolId int8 not null,
    externalInstrumentSymbolId varchar(50) not null,
    symbol varchar(40) not null,
    symbolType varchar(20) not null,
    symbols_instrumentId int8 not null,  /* Additional column, not visible from Java */
    primary key (instrumentSymbolId)
);

alter table InstrumentSymbol 
   add constraint FKcb138lkaiji2wh11275m77byk 
   foreign key (symbols_instrumentId) 
   references Instrument;
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • What do you mean under "hidden field"? – SternK Apr 09 '20 at 18:10
  • Improved the question. `InstrumentSymbol` has a column in the database called `symbold_instrumentId` which Hibernate automatically creates but there is no property associated with it. – Aaron Digulla Apr 09 '20 at 18:35
  • Still can not understand that. Do you use hibernate [schema generation](https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#schema-generation)? If so, this column should be firstly declared in the `InstrumentSymbol` entity. – SternK Apr 09 '20 at 19:15
  • Yes. With both the `@OneToMany` and the `@JoinColumn`, Hibernate will create an additional column in the database with a generated name. There is no need for declare the column in the Java source. This is convenient but causes problems for me when using a JPA Criteria Builder. I can't easily add a field because the same Java type is serialized to JSON. – Aaron Digulla Apr 09 '20 at 19:46

0 Answers0