facai
facai copied to clipboard
Custom JDBC table config lost when child relationships deferred
Consider a typical foreign key relationship between two tables like this:
--Database tables:
create table child
(
child_id varchar(40) not null primary key,
description varchar(200)
);
create table parent
(
parent_id varchar(40) not null
primary key,
child_id varchar(40) not null
references child,
parent_desc varchar(500)
);
, with factories defined like so:
(f/defactory child
:lambdaisland.facai.next-jdbc/table "child"
:facai.factoryory/primary-key :child-id
{:child-id #(str (random-uuid))
:description "This is the description"}
:traits
{:bar
{:with {:description "bar"}}})
(f/defactory parent
:lambdaisland.facai.next-jdbc/table "parent"
:facai.factoryory/primary-key :parent-id
{:parent-id #(str (random-uuid))
:child child
:parent-desc #(str (random-uuid))}
:traits
{:foo
{:with {:parent-desc "foo"}}})
when attempting to create!
sample data in Postgres using the lambdaisland.next.jdbc
namespace like so:
(fnj/create! {::fnj/ds ds
::fnj/fk-col-fn #(keyword (str (name %) "-id"))}
parent {
:with {:child (lambdaisland.facai.kernel/defer child {:traits [:bar]})}})
a Postgres Exception is thrown:
Execution error (PSQLException) at org.postgresql.core.v3.QueryExecutorImpl/receiveErrorResponse (QueryExecutorImpl.java:2676).
ERROR: relation "children" does not exist
Position: 13
Location: File: parse_relation.c, Routine: parserOpenTable, Line: 1376
Server SQLState: 42P01
This implies that the
:lambdaisland.facai.next-jdbc/table
value in the child
factory is not being used, as would be expected in this configuration. This works for the standard case with no defer
on the child factory, so it is probably related to the deferral.
Thanks for the report, I had a look but it isn't immediately trivial to fix, and I don't want to put much more effort into Facai. I also failed to get your example to run on H2, that would have helped a lot since it would've been easier to add a failing test case first.
Facai turned out to be a great proof of concept, but dogfooding it for a while did show it has some fundamental issues. One of them is the deferred abstraction which we're likely to get rid of.
I'm leaving Facai mostly as-is since it's used on a few dozen projects at this point, but any future effort will go towards a redesign in the form of Harvest.