maxmello
01/30/2023, 4:36 PMobject
tables and (companion) object
EntityClasses, have classes that are instantiated e.g. in ktor module on app start, which would give the ability to properly pass in dependencies instead of relying on global variables? For example, for my own extensions of Exposed for handling jsonb columns, I need to pass in a Jackson ObjectMapper
. Right now, I have a global object where I set a var on application start, but the Exposed part is the only part of my ktor application not having dependencies properly passed in via constructor params (I don’t use any DI framework).maxmello
01/31/2023, 12:53 PMreferrersOn
, backReferencedOn
etc. actual requires EntityClass
to be used as objects. I tried the following:
val manyRefs by application.entityClass<ManyRefEntityClass>().referrersOn(application.table<ManyRefTable>().example)
Where I build a function using reified types to get the entityClass dynamically via application, but the compiler does not recognize `referrersOn`in this example. Instead if I have any object: EntityClass defined, IntelliJ will try to import that objects referrersOn
function.Richard
01/31/2023, 2:39 PMObjectMapper
• Use context receivers so a ObjectMapper
is in scope
What specific obstacle are you running into with the extensions you mention? Do you have a partial example to share?Richard
01/31/2023, 2:44 PMObjectMapper
across all classes is a godo thingmaxmello
01/31/2023, 3:56 PMTable
or EntityClass
just by its name, or do http requests inside the saving logic of an entity. So really my requirement is, inside Table
or EntityClass
constructors or methods, I already need to have access to other objects that are only initialized in the application starting module, so it would be best if I can just initialize all the DB classes in the same manner rather than having to use singletons with lateinit vars for example.
I think I found a solution that works well enough for now:
• Create a class SchemaHandler that stores reference to all Table / EntityClass objects
• Register this SchemaHandler with the application (now, everything with access to application can also access the schemaHandler)
• Inside the app module / initialization, instantiate 1 instance of each EntityClass/Table and registering this with the SchemaHandler
• Here, we need to ensure proper order, such that no table is created first that references another table that does not yet exist
• To make Entity initialization work, create a common superclass to all EntityClasses overriding entityCtor: ((EntityID<Long>) -> E)? = null
, which usually calls a 1 param constructor. Instead, we pass in the table
here as a 2nd parameter (all implementations require to conform to this standard, having the table as 2nd param)
• Instead of writing something like val bookShop = reference("bookShop", BookShopTable)
, I now write val bookShop = reference("bookShop", application.table<BookShops>())
because inside the table init, I have access to my application now
• The only problem is that usage of Extension functions inside EntityClass
seem to require static access to them, so I create 1 dummy object: EntityClass and import the extension functions from there
Its not perfect but seems to work and from a library user perspective will hopefully be cleaner 😅 Sorry for wall of text its hard to explainRichard
01/31/2023, 4:36 PM