neo4j / sdn-rx

Nextgen Spring Data module for Neo4j supporting (not only) reactive data access and immutable support
https://neo4j.github.io/sdn-rx
Apache License 2.0
65 stars 23 forks source link

Impossible inheritance with data classes in Kotlin #271

Closed haris-zynka closed 4 years ago

haris-zynka commented 4 years ago
  1. There's no way to have repository for an interface
  2. Having 1 open class in Kotlin with all necessary fields for generic items and data class extending it will causeCaused by: java.lang.IllegalStateException: Duplicate definition of properties [...

Now I need to have a simple generic class which will represent things I need FROM the database as use case is such that user side needs to fetch anything that has those values. So I need simple thing that will go into database fetch items that contain specific label and project only those values. I'm unaware does spring support this but I tried merging "Projections" with repositories of real items by using open class

One more thing: I tried having Projection classes and those do not support List of items. If in any case I try to have simple DTO which contains list of other items and their "stripped down" DTOs it will return whatever I put as default. I'm unaware how this works in java but by your documentation I should be able to get anything related to 1 node. However Example 60 in this link shows only 1 node connected to starting node. Should this work for List as well?

EDIT: I avoid this issue by having "fake" data class which implements that interface, I put all values there and leave generic type as interface. Then I use "fake" type to make a repository and use projections to extract interface instead of that class. "fake" class has primary label equal to interface name and other classes have that label as alternative. I'm pretty sure that this is hackish way and it's not as good. If it's the only way and OK then I'm fine with it.

Example:

interface Something {
  val id: String?
  val name: String?
}
@Node(primaryLabel = "Something")
data class SomethingElse(@Id override val id: String? = null, override val name: String = "else") : Something

@Node(primaryLabel = "Actual", labels = ["Something"])
data class Actual(@Id override val id: String? = null, override val name: String = "actual implementation used", val morevalues: String = "") : Something

@Node(primaryLabel = "AnotherActual")
data class AnotherActual(@Id override val id: String? = null, override val name: String = "actual implementation used", val attrib: String = "", val number: Double = 0.0) : Something

interface Repo : ReactiveNeo4jRepository<SomethingElse, String> { // here I create repo for interface implementation
  fun findSomethingById(id: String) : Mono<Something> // here I use projections but it generates SomethingElse type of object
  fun findDynamicById(id: String, type: Class<T>) : Mono<T> // thanks to dynamic projections this way I can get actual fields if I need
}

As stated I think there might be a better solution or possibility to implement something in SDN/RX to avoid above "solution"

meistermeier commented 4 years ago

Thanks for reporting this. Since we are in a migration process to the original Spring Data Neo4j and have to archive this repository, the issue also go migrated to: https://jira.spring.io/browse/DATAGRAPH-1340 Please watch or comment on the issue in Jira for further communication.