I agree, explicit class literals would be much nicer, but I'm not able to picture how that gets passed around. Do you have an example to share? On May 27, 2016 6:03 AM, "Lukas Eder" <[email protected]> wrote:
> That's a nice idea. With your current design, this will work. But beware, > you're entering a minefield here. The Java compiler erases (most) generic > type information. This works for very specific reasons (i.e. your subclass > terminally binding the generic types R, T, and E to the respective concrete > types). There are other situations, where you cannot discover the "actual > type arguments" through reflection. > > I usually prefer to pass around explicit class literals, such as > GalleryRecord.class. > > Hope this helps, > Lukas > > 2016-05-26 23:07 GMT+02:00 Devin Austin <[email protected]>: > >> Okay, sorry for the spam, but I think I found a solution: >> >> public abstract class BaseService <R extends Record, T extends Table<R>, >> E>{ >> >> // ... >> private Class<E> recordClass; >> >> >> public BaseService(DSLContext s) { >> // ... >> this.recordClass =(Class<E>) ((ParameterizedType) getClass() >> >> .getGenericSuperclass()).getActualTypeArguments()[0]; >> } >> >> I'll continue testing this, but so far *knock on wood* things seem to be >> working. I would definitely like any feedback you have though. >> >> Thanks again, >> -Devin >> >> On Thursday, May 26, 2016 at 2:44:16 PM UTC-6, Devin Austin wrote: >>> >>> Looks like I jumped the gun on this a bit, it doesn't actually work. >>> I'll report back if I find anything else. >>> >>> On Thu, May 26, 2016 at 1:58 PM, Devin Austin <[email protected]> >>> wrote: >>> >>>> Hi Lukas, >>>> >>>> I don't know how dirty this is, but I may have found a solution. >>>> >>>> If you look here: >>>> https://gist.github.com/dhoss/eb94f0e33138e51c478a033d9e70cc4e#file-baseservice-java-L22-L28 >>>> and here: >>>> https://gist.github.com/dhoss/eb94f0e33138e51c478a033d9e70cc4e#file-baseservice-java-L74, >>>> this mitigates the need for a mapper() method. Some preliminary testing >>>> shows that it seems to work, so far. >>>> >>>> I'm aware of the type safety issues, but barring any issues that come >>>> up, this seems to do the trick. What are your thoughts? >>>> >>>> Thanks! >>>> >>>> On Thu, May 26, 2016 at 12:15 PM, Devin Austin <[email protected]> >>>> wrote: >>>> >>>>> Hi Lukas, >>>>> >>>>> I am really grateful for your attentiveness to this. It's really >>>>> helping me pull together some concepts I've struggled with for some time. >>>>> >>>>> You have to decide whether you want to expose the jOOQ API to >>>>>> consumers of your services (e.g. Field, SortField, Condition, etc.) or if >>>>>> you want to implement your own criteria API. From then on it's just yak >>>>>> shaving. >>>>> >>>>> >>>>> I think at this point it's going to be easiest to sort of lump common >>>>> queries into service classes and use whatever available DAO methods get >>>>> generated. I've had a lot of success in the past just dropping down >>>>> closer >>>>> to bare metal when features I want aren't immediately present in the >>>>> current layer. >>>>> >>>>> >>>>> >>>>>> Yes it is. I cannot seem to find the issue on GitHub right now, but >>>>>> it might be a nice feature. The only question is the same as the one >>>>>> above. >>>>>> Should we really expose the jOOQ API? >>>>> >>>>> >>>>> Please do let me know when/if you find it, and I'll be happy to fork >>>>> and submit PRs. I think it would at least be nice to have the ability to >>>>> either call something like .sort(COLUMN.asc()), or pass in a >>>>> "configuration" object that potentially contains limit, order by and group >>>>> by information, or pass in a parameter somehow. My background is mostly >>>>> ruby/perl, so I don't know how this even translates to Java but something >>>>> like this would be neat: .fetchAllBySlug(:order_by => 'created_on DESC'). >>>>> I realize there's not a clean way to implement anonymous maps in Java, but >>>>> it conveys my point, I think. >>>>> >>>>> Thus far, caching has been out of scope for jOOQ, except perhaps for >>>>>> result set caching as displayed in this blog post: >>>>>> http://aakashjapi.com/caching-with-jooq-and-redis >>>>>> >>>>>> I'm always open for discussion though. What specific use-cases did >>>>>> you have in mind? >>>>>> >>>>> >>>>> I went off on a tangent there a bit, so I don't have anything jOOQ >>>>> specific in terms of caching. >>>>> >>>>> How about implementing that using either a trigger, or the DDL >>>>>> "DEFAULT" clause? >>>>>> >>>>>> If you want to implement that on the jOOQ layer, the RecordListener >>>>>> SPI might be interesting to you, given that you intend to implement a >>>>>> CRUD >>>>>> layer anyway. >>>>>> >>>>> >>>>> I dug through my code and I actually have the default getting set in >>>>> my add() method. The problem I'm running into is still my mapper. Right >>>>> after I submitted my question regarding the mapping error, I had actually >>>>> implemented what you suggested for the generics, but it still doesn't like >>>>> my method signature (up to date code: >>>>> https://gist.github.com/dhoss/d40edcbfc111ad7604bc8ce0d3c9bdec): >>>>> [ERROR] Failed to execute goal >>>>> org.apache.maven.plugins:maven-compiler-plugin:3.2:compile >>>>> (default-compile) on project gallery: Compilation failure >>>>> [ERROR] >>>>> /home/devin/projects/lumos-gallery/gallery/src/main/java/com/lumos/service/BaseService.java:[73,14] >>>>> method map in interface org.jooq.Result<R> cannot be applied to given >>>>> types; >>>>> [ERROR] required: org.jooq.RecordMapper<? super org.jooq.Record,E> >>>>> [ERROR] found: org.jooq.RecordMapper<R,P> >>>>> [ERROR] reason: cannot infer type-variable(s) E >>>>> [ERROR] (argument mismatch; org.jooq.RecordMapper<R,P> cannot be >>>>> converted to org.jooq.RecordMapper<? super org.jooq.Record,E>) >>>>> >>>>> At this point, I just need something that will turn the objects I get >>>>> back from jOOQ into my POJOs. It would be really neat if I could get the >>>>> "implement your own damn mapper" per table/service working. Previously, I >>>>> had each table service passing a lambda to fetch() (pulled from here: >>>>> https://github.com/lukaseder/minitwit/blob/master/src/main/java/com/minitwit/dao/MessageDao.java#L69), >>>>> and that worked fine, but it doesn't lend itself very well to a base >>>>> service that individual table service classes can inherit default CRUD >>>>> methods from. I've been staring at this code for too long and am making >>>>> things convoluted in my head, so forgive me if I'm making this whole thing >>>>> too complicated, but making the record mapper piece generic enough, and >>>>> implemented in the correct spot is what's confusing me the most. Looking >>>>> through the docs, you can add one in your DSL context configuration ( >>>>> http://www.jooq.org/doc/3.7/manual/sql-execution/fetching/pojos-with-recordmapper-provider/), >>>>> but that looks like it's still expecting a distinct class name to >>>>> fetchInto(). You can also call .map() after .fetch() and pass it a record >>>>> mapper ( >>>>> http://www.jooq.org/doc/3.7/manual/sql-execution/fetching/recordmapper/), >>>>> which is what I'm trying to do, but running into the issue above. I'm >>>>> certainly open to more intelligent approaches. >>>>> >>>>> By the way, I'm going to write up a tutorial on all this once it gets >>>>> sorted out and I'm more than happy to contribute documentation if it fits >>>>> in anywhere. >>>>> >>>>> Thanks, >>>>> -Devin >>>>> >>>>> >>>>> On Thu, May 26, 2016 at 11:02 AM, Lukas Eder <[email protected]> >>>>> wrote: >>>>> >>>>>> Hi Devin, >>>>>> >>>>>> Here's the promised follow-up >>>>>> >>>>>> 2016-05-25 20:28 GMT+02:00 Devin Austin <[email protected]>: >>>>>> >>>>>>> 3. I thought it might be easier to just extend the DAOImpl class >>>>>>> like you suggested, but I'm still left with figuring out how to >>>>>>> shoe-horn >>>>>>> in sorting and such, so I don't think that's a viable route at this >>>>>>> point. >>>>>>> >>>>>> >>>>>> You have to decide whether you want to expose the jOOQ API to >>>>>> consumers of your services (e.g. Field, SortField, Condition, etc.) or if >>>>>> you want to implement your own criteria API. From then on it's just yak >>>>>> shaving. >>>>>> >>>>>> >>>>>>> I would, however, be more than happy to help contribute sorting and >>>>>>> limiting conditions if that's on the future TODO list. >>>>>>> >>>>>> >>>>>> Yes it is. I cannot seem to find the issue on GitHub right now, but >>>>>> it might be a nice feature. The only question is the same as the one >>>>>> above. >>>>>> Should we really expose the jOOQ API? >>>>>> >>>>>> >>>>>>> 4. A slight tangent, but looking at my code I think it would be >>>>>>> nicer to have an interface the lays out the CRUD contract, gets >>>>>>> implemented >>>>>>> in a CRUD base class, and then subclassed as needed. My hope would be >>>>>>> to >>>>>>> make my database CRUD a good deal more encapsulated and lighter weight, >>>>>>> and >>>>>>> allow me to have things like a cache service that's still a service but >>>>>>> completely unrelated to the database CRUD operations. I'm probably just >>>>>>> thinking out loud, but if that makes any of this simpler, please let me >>>>>>> know your thoughts. >>>>>>> >>>>>> >>>>>> Thus far, caching has been out of scope for jOOQ, except perhaps for >>>>>> result set caching as displayed in this blog post: >>>>>> http://aakashjapi.com/caching-with-jooq-and-redis >>>>>> >>>>>> I'm always open for discussion though. What specific use-cases did >>>>>> you have in mind? >>>>>> >>>>>> >>>>>>> I am certainly not adverse to doing something else for my mapping >>>>>>> code. I really just need to have the GALLERIES.COVER_PHOTO get set >>>>>>> to either the value in the database or the default cover photo, which I >>>>>>> suppose I could just set by default when inserting the record, so >>>>>>> there's a >>>>>>> value for that column in the database. >>>>>>> >>>>>> >>>>>> How about implementing that using either a trigger, or the DDL >>>>>> "DEFAULT" clause? >>>>>> >>>>>> If you want to implement that on the jOOQ layer, the RecordListener >>>>>> SPI might be interesting to you, given that you intend to implement a >>>>>> CRUD >>>>>> layer anyway. >>>>>> >>>>>> Cheers, >>>>>> Lukas >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to a topic in >>>>>> the Google Groups "jOOQ User Group" group. >>>>>> To unsubscribe from this topic, visit >>>>>> https://groups.google.com/d/topic/jooq-user/KUPyMa2581g/unsubscribe. >>>>>> To unsubscribe from this group and all its topics, send an email to >>>>>> [email protected]. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> Devin Austin >>>>> https://www.stonecolddev.in >>>>> >>>> >>>> >>>> >>>> -- >>>> Devin Austin >>>> https://www.stonecolddev.in >>>> >>> >>> >>> >>> -- >>> Devin Austin >>> https://www.stonecolddev.in >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "jOOQ User Group" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to a topic in the > Google Groups "jOOQ User Group" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/jooq-user/KUPyMa2581g/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "jOOQ User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
