Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
* @param version whether the column is a version column.
* @param ref whether the column is a lazily fetched record.
* @param metamodel the metamodel for the column.
* @param secondaryMetamodel the secondary metamodel for the column, in case of foreign keys.
* @param secondaryMetamodel the secondary metamodel for the column: the referenced primary key metamodel for
* foreign keys, or the component's own metamodel for compound key components.
*/
public record ColumnImpl(
@Nonnull Name columnName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,12 @@ private static void createColumns(@Nonnull BuildContext ctx,
return;
}
ColumnName columnName = getColumnName(field, ctx.builder().columnNameResolver());
emitColumns(ctx, field, columnMetamodel, null, spec, keyScope, List.of(columnName), List.of(spec.dataType()), List.of(spec.dataType()));
// Compound key components are registered under the key's group metamodel so that compound
// lookups resolve to all key columns. The component's own metamodel is retained as the
// secondary metamodel so that per-component metamodels, as exposed by generated metamodel
// classes and Key.flatten(), resolve to their individual column as well.
Metamodel<Data, ?> componentMetamodel = columnMetamodel != ownMetamodel ? ownMetamodel : null;
emitColumns(ctx, field, columnMetamodel, componentMetamodel, spec, keyScope, List.of(columnName), List.of(spec.dataType()), List.of(spec.dataType()));
} catch (SqlTemplateException e) {
throw new UncheckedSqlTemplateException(e);
}
Expand Down
19 changes: 19 additions & 0 deletions storm-core/src/test/java/st/orm/core/ModelImplIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand All @@ -14,6 +15,7 @@
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import st.orm.Metamodel;
import st.orm.core.model.City;
import st.orm.core.model.Owner;
import st.orm.core.model.Pet;
Expand Down Expand Up @@ -322,6 +324,23 @@ public void testVetSpecialtyModelCompoundPk() {
assertEquals(2, primaryKeyColumnCount, "VetSpecialty should have 2 primary key columns");
}

@Test
public void testVetSpecialtyCompoundPkComponentColumns() throws Exception {
// Per-component metamodels of a compound key resolve to their individual column, while the
// compound key's own metamodel keeps resolving to all key columns.
var orm = ORMTemplate.of(dataSource);
var model = orm.entity(VetSpecialty.class).model();
var vetIdColumns = model.getColumns(Metamodel.of(VetSpecialty.class, "id.vetId"));
assertEquals(1, vetIdColumns.size());
var specialtyIdColumns = model.getColumns(Metamodel.of(VetSpecialty.class, "id.specialtyId"));
assertEquals(1, specialtyIdColumns.size());
assertNotEquals(vetIdColumns.getFirst().name(), specialtyIdColumns.getFirst().name());
var compoundColumns = model.getColumns(Metamodel.of(VetSpecialty.class, "id"));
assertEquals(2, compoundColumns.size());
assertTrue(compoundColumns.contains(vetIdColumns.getFirst()));
assertTrue(compoundColumns.contains(specialtyIdColumns.getFirst()));
}

// Visit model with @Version timestamp

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import st.orm.DbTable;
import st.orm.Entity;
import st.orm.FK;
import st.orm.Metamodel;
import st.orm.PK;
import st.orm.Persist;
import st.orm.PersistenceException;
Expand Down Expand Up @@ -83,6 +84,17 @@ public class TemplatePreparedStatementIntegrationTest {
@Autowired
private PetRepository petRepository;

@Test
public void testSelectCompoundPkComponent() {
// Compound key component metamodels resolve to their individual column in templates.
try (var query = ORMTemplate.of(dataSource).query(raw("""
SELECT DISTINCT \0
FROM \0""", Metamodel.of(VetSpecialty.class, "id.specialtyId"), VetSpecialty.class)).prepare();
var stream = query.getResultStream(Integer.class)) {
assertFalse(stream.filter(Objects::nonNull).toList().isEmpty());
}
}

@Test
public void testSelectPet() {
// Template expansion auto-joins owner and city. 12 owned pets span 10 distinct owners.
Expand Down
Loading