snowe
04/17/2020, 8:31 PMpublic abstract class AbstractProjector<ID extends Serializable, DTO extends AbstractView, DAO extends AbstractViewDao> {
protected final JpaRepository<DAO, ID> repository;
protected final Function<DAO, DTO> toDto;
protected final Function<DTO, DAO> toDao;
protected AbstractProjector(JpaRepository<DAO, ID> repository,
Function<DAO, DTO> toDtoFunction,
Function<DTO, DAO> toDaoFunction) {
this.repository = repository;
this.toDto = toDtoFunction;
this.toDao = toDaoFunction;
}
...
that is used like this:
public class WorkItemProjector extends AbstractProjector<WorkItemId, WorkItemView, WorkItemViewDao> {
@Autowired
public WorkItemProjector(WorkItemViewRepository repository) {
super(repository, WorkItemViewDao::toDto, WorkItemViewDao::toDao);
}
...
}
Here is the repository:
interface WorkItemViewRepository : JpaRepository<WorkItemViewDao?, WorkItemId?> {...}
Here is the WorkItemView
and WorkItemViewDao
data class WorkItemView(
val workItemId: WorkItemId,
val decisionId: SomeId,
val appId: SomeId,
override var tenantId: TenantId,
val workItemStatus: WorkItemListType? = null
) : AbstractView, Serializable
@Entity(name = "…")
@Table(name = "…")
data class WorkItemViewDao(
@Id var workItemId: WorkItemId,
@AttributeOverrides(AttributeOverride(name = "id", column = Column(name = "…")))
var decisionId: SomeId,
@AttributeOverrides(AttributeOverride(name = "id", column = Column(name = "…")))
var appId: SomeId,
override var tenantId: TenantId,
@Type(type = "Json", parameters = arrayOf(Parameter(name = "type", value = "…")))
@Column(name = "data") var workItemView: WorkItemView
) : AbstractViewDao {
companion object {
@JvmStatic
fun toDao(view: WorkItemView) = WorkItemViewDao(view.workItemId, view.decisionId, view.appId, view.tenantId, view)
@JvmStatic
fun toDto(dao: WorkItemViewDao?) = dao?.workItemView
}
}
When converting this to Kotlin, you can guess the issue.
AbstractProjector
abstract class AbstractProjector<ID : Serializable?, DTO : AbstractView?, DAO : AbstractViewDao?> protected constructor(
protected val repository: JpaRepository<DAO, ID>,
protected val toDto: (DAO) -> DTO,
protected val toDao: (DTO) -> DAO
) {..}
WorkItemProjector
class WorkItemProjector(repository: WorkItemViewRepository) :
AbstractProjector<WorkItemId?, WorkItemView?, WorkItemViewDao?>(
repository,
WorkItemViewDao::toDto,
WorkItemViewDao::toDao
) {…}
and the issue is show in an image below.
Here are some of the function signatures (in AbstractProjector
) that demonstrate how I can’t effectively split this into multiple interfaces with different out/in
variances (I think)
protected fun save(tenantId: TenantId?, viewCreator: () -> DTO) {
protected fun conditionallyUpdate(viewId: ID, proceedWithUpdate: (DTO) -> Unit, viewUpdater: (DTO) -> DTO) {
protected fun update(viewId: ID, viewUpdater: (DTO) -> DTO) {
protected fun update(daoSupplier: Supplier<DAO>, viewUpdater: (DTO) -> DTO) {
protected fun updateDao(viewId: ID, viewUpdater: (DAO) -> DAO) {
protected fun delete(viewId: ID) {
private fun update(viewDao: DAO, viewUpdater: (DTO) -> DTO) {
Any clue on this would be great.