diff --git a/annotation-processor/src/main/kotlin/pl/touk/krush/source/SelfReferencesFunctions.kt b/annotation-processor/src/main/kotlin/pl/touk/krush/source/SelfReferencesFunctions.kt index c19e4bd..1156d10 100644 --- a/annotation-processor/src/main/kotlin/pl/touk/krush/source/SelfReferencesFunctions.kt +++ b/annotation-processor/src/main/kotlin/pl/touk/krush/source/SelfReferencesFunctions.kt @@ -49,16 +49,16 @@ fun buildToEntityFuncSelf(entityType: TypeElement, entity: EntityDefinition): Fu private fun generateAssociationMappings(entity: EntityDefinition) = entity.getAssociations(AssociationType.MANY_TO_ONE, AssociationType.ONE_TO_ONE) .filter { assoc -> assoc.mapped } - .map { - val name = it.name - val targetName = it.target.simpleName - if (!it.nullable) { + .map { assoc -> + val name = assoc.name + val targetName = assoc.target.simpleName + if (!assoc.nullable) { "\t$name = this.to$targetName()" } else { - if (entity.hasSelfReferentialAssoc()) { - "\t$name = this.row[${entity.name}Table.${name}Id]?.let { nextAlias?.let { this.to$targetName(nextAlias, null) } }" + if (assoc.isSelfReferential) { + "\t$name = this.row[alias[${entity.tableName}.${assoc.defaultIdPropName()}]]?.let { nextAlias?.let { this.to$targetName(nextAlias, null) } }" } else { - "\t$name = this[${entity.name}Table.${name}Id]?.let { this.to$targetName() }" + "\t$name = this.row[alias[${entity.tableName}.${assoc.defaultIdPropName()}]]?.let { this.to$targetName() }" } } } diff --git a/example/src/main/kotlin/pl/touk/krush/realreferences/Category.kt b/example/src/main/kotlin/pl/touk/krush/realreferences/Category.kt index 6bd2be8..eeb2eea 100644 --- a/example/src/main/kotlin/pl/touk/krush/realreferences/Category.kt +++ b/example/src/main/kotlin/pl/touk/krush/realreferences/Category.kt @@ -1,19 +1,18 @@ package pl.touk.krush.realreferences +import java.util.* import javax.persistence.* @Entity @Table(name = "category") data class Category( @Id - @GeneratedValue - val id: Long? = null, + val uuid: UUID = UUID.randomUUID(), @Column val name: String, @ManyToOne - @JoinColumn(name = "parent_id") val parent: Category?, @OneToMany(mappedBy = "parent") diff --git a/example/src/main/kotlin/pl/touk/krush/realreferences/Entry.kt b/example/src/main/kotlin/pl/touk/krush/realreferences/Entry.kt new file mode 100644 index 0000000..8ccf4f9 --- /dev/null +++ b/example/src/main/kotlin/pl/touk/krush/realreferences/Entry.kt @@ -0,0 +1,21 @@ +package pl.touk.krush.realreferences + +import java.util.* +import javax.persistence.* + +@Entity +@Table(name = "entry") +data class Entry( + @Id + val uuid: UUID = UUID.randomUUID(), + + @Column + val name: String = "Data Entry", + + @ManyToOne + val category: Category? = null, + + @JoinTable(name = "related_entries") + @ManyToMany + val relatedEntries: List = emptyList() +) diff --git a/example/src/test/kotlin/pl/touk/krush/realreferences/CategoryTest.kt b/example/src/test/kotlin/pl/touk/krush/realreferences/CategoryTest.kt index 47f3ea9..9361e7f 100644 --- a/example/src/test/kotlin/pl/touk/krush/realreferences/CategoryTest.kt +++ b/example/src/test/kotlin/pl/touk/krush/realreferences/CategoryTest.kt @@ -23,7 +23,7 @@ class CategoryTest: BaseDatabaseTest() { val child2 = CategoryTable.insert(Category(name = "child2", parent = parent)) val categories = - CategoryTable.join(parentAlias, JoinType.LEFT, CategoryTable.parentId, parentAlias[CategoryTable.id]) + CategoryTable.join(parentAlias, JoinType.LEFT, CategoryTable.parentUuid, parentAlias[CategoryTable.uuid]) .selectAll() .map { it.toCategory(parentAlias) } @@ -31,7 +31,7 @@ class CategoryTest: BaseDatabaseTest() { .containsExactlyInAnyOrder(parent, child1, child2) val fullCategoryMapping = - CategoryTable.join(parentAlias, JoinType.LEFT, CategoryTable.parentId, parentAlias[CategoryTable.id]) + CategoryTable.join(parentAlias, JoinType.LEFT, CategoryTable.parentUuid, parentAlias[CategoryTable.uuid]) .selectAll() .toCategoryList(parentAlias) @@ -40,4 +40,25 @@ class CategoryTest: BaseDatabaseTest() { } } + @Test + fun shouldReferenceCategoriesShallowlyForSelfReferentialEntities() { + transaction { + SchemaUtils.create(CategoryTable, EntryTable, EntryRelatedEntriesTable) + + val category = CategoryTable.insert(Category(name = "parent", parent = null)) + + val entryWithoutCategory = EntryTable.insert(Entry()) + val entry = EntryTable.insert(Entry(category = category, relatedEntries = listOf(entryWithoutCategory))) + + val entryMapping = EntryTable + .join(CategoryTable, JoinType.LEFT, EntryTable.categoryUuid, CategoryTable.uuid) + .join(EntryRelatedEntriesTable, JoinType.LEFT, EntryTable.uuid, EntryRelatedEntriesTable.entrySourceUuid) + .selectAll() + .toEntryList() + + assertThat(entryMapping) + .containsExactlyInAnyOrder(entry, entryWithoutCategory) + + } + } }