>> How is it different from this one? >> >> http://www.jooq.org/javadoc/latest/org/jooq/Record.html#from(java.lang.Object) > > > It doesn't use reflection. Since I know all the fields and getters and > setters, it's easy to generate a method that just calls all of them: [...]
That is a nice idea. Care to contribute? :-) In essence, the code-generator could do this: - If records AND pojos are generated, it would generate into(POJO) and from(POJO) methods - If records AND interfaces are generated, it would generate into(IFace) and from(IFace) methods The second rule would override the first. I'll file this as feature request #1689 https://github.com/jOOQ/jOOQ/issues/1689 Besides, from your logic, I'd say that adding a general <E> E Record.into(E) method might be a useful addition, copying data into previously instanciated custom POJO types: https://github.com/jOOQ/jOOQ/issues/1688 > Maybe it would make sense to combine all columns related to the PK into a PK > Java type, so the whole PK gets a single "has changed" flag. I have thought about this before. Having multi-column primary keys modelled as a single object would help resolve some API issues that can currently not be resolved - e.g. generated DAOs don't really support multi-column PKs. Adding such PK support might look simple at first, but the corresponding foreign keys might also have to be modelled accordingly, I guess. I'm not sure yet, if I want to go down that road. Anyway, let's track the idea as #1690: https://github.com/jOOQ/jOOQ/issues/1690 > But I have a feeling that this could cause nasty corner cases when someone > tries to manipulate the individual columns with setValue(field, ...); The PK Java object would have to encapsulate the same behaviour today's org.jooq.impl.Value internal object encapsulates. I.e. changing one PK column would mean that the whole PK can be considered as "changed". This is already the case today, although the information is distributed across multiple org.jooq.impl.Value objects. Record.setValue() has all the necessary information to update any PK's internal "changed" flags, should a PK member be changed individually through other API methods. With a sufficient number of test cases, I don't think that would be a problem. > Well, Hibernate solves this like so: If the PK is null, the identity > generator is started to assign a PK (well, I simplify but you get the idea) > and an INSERT will happen. If the PK is not null, it will UPDATE. Yes, I know this behaviour by Hibernate. In the early days of jOOQ, I have evaluated it against other options. > This feels natural because it uses the assumption that you can't have a > PK unless the record has been read from the DB. And if you have a PK, > then the DB must already know about it. This model might suit 90% of user needs. But jOOQ also accomodates those 10% who generate PK values in Java (using UUID's, explicit Oracle sequence calls, etc.). In those cases, the PK values are set explicitly upon a Record with the intent of executing an INSERT, not an UPDATE. In other words, you *can* have a PK value that the DB does not yet know about. The only way to be sure that the PK is already in the DB is when the Record was actually fetched from the DB. Now, of course, this leads to the inverse problem that you, as a user, cannot set a PK value upon a (new) Record, without jOOQ assuming that you intend to INSERT this Record. > So maybe a good solution would be to modify jOOQ to support a similar > behavior. I prefer not to change that logic at this stage. It might break quite a few applications. > With my suggested changes in the Configuration class, it would be simple > to add the PK generator to it. Everything else should then be a purely > internal change of the logic. I'm still exploring alternatives of supporting PK generators in Record.store() calls. I also like the idea to support a central authority for this in the Configuration / Settings objects. In fact, I would like to go much farther and support something like an org.jooq.Trigger type, that can be configured centrally in the Configuration. This trigger type could then be parameterised to listen to any type of statement event. I would like to get inspiration from standard SQL triggers, which feature: - Scope (i.e. listening to all events, or just to events for some tables) - Statement type (i.e. listening to any statement, or just inserts/updates, etc) - Conditions (i.e. triggered always, or just when some condition is met) - Before / After - etc. Such triggers would be implemented as ExecuteListeners. Let's track this, too: https://github.com/jOOQ/jOOQ/issues/1691 Cheers Lukas
