cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kelven Yang <kelven.y...@citrix.com>
Subject Re: persistence layer
Date Tue, 03 Dec 2013 01:27:49 GMT
I generally in agree with what Darren has pointed. Within the context of
ACS, declarative transaction support is not as urgent as solving the
problem as we are having in writing queries. Solving basic CRUD and query
problem alone in a consistent pattern can move CloudStack persistence
layer a big step ahead. And the good part of it is that we can do it
incrementally, which I think it¹s the key for us to really move forward
quickly.

I saw a lot of efforts trying to hide the complexity of underlying problem
but eventually end up to a more complex solution. With that said, myself
actually prefer a simple solution that is close to SQL as natural but
solves the DB-agnostic problem to a reasonable level, I don¹t like too
much of the idea trying to hide SQL completely away from developers. So
far JOOQ sounds like a good candidate to me.

Kelven

On 12/2/13, 3:07 PM, "Frank Zhang" <Frank.Zhang@citrix.com> wrote:

>Hi Lukas:
>	Thank for detailed reply, see my comments inline
>
>> 
>> Hi Frank,
>> 
>> Thank you for your detailed feedback. This is very interesting insight
>>for me and
>> for Data Geekery. Let me try to address your concerns by first
>>categorising
>> them into the following items (please correct me if I might have
>> misunderstood).
>> 
>> - A concern about Spring support.
>> - A concern about standards (JPA)
>> - A concern about CRUD verbosity
>> - A concern about fluent APIs vs. SQL
>> - A concern about fluent APIs vs. custom query building APIs
>
>Your explanation frees my concerns from last three items. I don't
>carefully read
>entire JOOQ document and I think most people won't when they try to get
>an overall picture of a new project.
>
>So if we can highlight these items(especially CRUD verbosity and custom
>query builder)
>somewhere, it would be more appealing to developers who have
>JPA/Hibernate background.
>
>> 
>> Spring support
>> ===========
>> It is true that we cannot offer you a "formal" affiliation with Spring
>>(or rather
>> with Oliver Gierke, the lead developer behind Spring Data). I have been
>> observing this collaboration between Spring Data and QueryDSL and I
>>feel that
>> it is a strategic alliance that mutually benefits both vendors.
>> QueryDSL gets some more traction by being auto-shipped to a much broader
>> audience, whereas Spring Data gets a fluent API for both JPA and SQL.
>> 
>> From our perspective, we want jOOQ to be entirely independent of any
>> transaction and connection pooling API as this facilitates integration
>>with JTA
>> transaction modelling and other models. We believe that by keeping
>>things
>> simple and by separating concerns, you will get a stack that is better
>>focused on
>> your individual needs. In that way, we believe that you should be able
>>to
>> combine Spring IOC with jOOQ just as much as with JEE components.
>> 
>> Most importantly, Spring Data, much like JDO in the past and like
>>QueryDSL
>> today aim for integrating NoSQL databases into a unified API, which we
>>find a
>> poor fit, as transaction models, data models, query models are
>>fundamentally
>> different between these various data stores. We believe that by
>>pursuing such
>> unification, frameworks are easily distracted from sound SQL support. We
>> highly value Spring's transaction model simplification and this has
>>worked well
>> with jOOQ in the past.
>
>My whole point here is about declarative transaction management which is
>the
>most compelling part of Spring Data(from Spring's own words). Just did
>more
>research that JOOQ is a DB access layer it won't involve in any
>transaction
>management stuff. If my understanding is correct, it should automatically
>work
>with Spring TX? Am I right?
>
>No matter the answer, JOOQ should give the best practice in document,
>searching chapter names in http://www.jooq.org/doc/3.2/manual/
>returns nothing about transaction and I have seen people asking
>similar question on Stack Overflow. I saw your answer too :)
>
>http://stackoverflow.com/questions/15159842/how-to-start-transaction-and-r
>ollback-with-jooq
>
>it's very true that we can draw a clear boundary between DB access layer
>and
>transaction management, but for most of time users don't care about this
>because
>they are searching an entire solution for DB. Even if JOOQ developers know
>transaction management is not focus of this project, they still need to
>tell their users
>the best way to go instead of letting user figure out it themselves.
>
>I don't think JOOQ has to integrate with SpringDB like QueryDSL does, for
>example,
>having a JOOQTemplate. But I do think integrating with Spring TX is
>important
>given it's popularity.
>
>
>> 
>> Standards (JPA)
>> ============
>> Now, one of your arguments in favour of JPA is the non-lock-in. Spring
>>has been
>> challenging JEE standards for quite some time and there is no other
>>vendor in
>> the market to replace Spring once you build upon Spring. Even more so,
>>by
>> choosing a Spring+QueryDSL combination, you get an equally strong
>>vendor-
>> lockin (or even a stronger one, as the stack gets more
>> complex) than when choosing Spring+jOOQ. If standards are important to
>>you, I
>> suggest you only use JPA and Criteria Query (Note, that JEE also
>>supports IoC).
>> And I'm sure that Adam Bien will agree with me on this :-) But even
>>then, you
>> will have a hard time migrating from Hibernate to EclipseLink or
>>OpenJPA as
>> the implementations are subtly different in many ways.
>> 
>> The decision is up to you, and I fully understand these concerns.
>>Standards are a
>> good thing because many disparate things from various vendors have been
>> unified and hopefully matured over time. But vendors also innovate and
>>thus
>> deviate from the standard again. Without such deviation, there would be
>>no
>> more progress, nor innovation in a standard. Take EclipseLink for
>>instance, a
>> JPA implementation that has started to "flirt" with NoSQL
>> support:
>> http://wiki.eclipse.org/EclipseLink/Examples/JPA/NoSQL
>> 
>> The above is orthogonal to JPA and will add lots of complexity to this
>>particular
>> implementation. JDO was another standard that has attempted to integrate
>> other, non-relational data stores in a single API, yet it has not
>>succeeded,
>> leaving a pretty much dead standard.
>> 
>> Now, while you are absolutely right by saying that you cannot switch the
>> implementation of the jOOQ API at the moment, we're striving to
>>innovate on
>> the standards front as we see room for various JSRs in the area of
>>RDBMS meta
>> modelling (beyond JDBC's DatabaseMetaData), internal DSL modelling in
>> general, SQL DSL modelling in particular. We believe that jOOQ is the
>>most
>> innovative platform for SQL to Java integration in the market at the
>>moment
>> 
>
>I strongly agree with the point that "none lock-in" is actually in theory
>most of time,
>In reality, there is more or less you have to do or sacrifice when moving.
>
>My concern here is about SQL engine layer. The SQL engine I mean is the
>part which
>generates final SQL statement. For my perspective, JOOQ is DSL API + SQL
>engine,
>where DSL API is the main business.  My understanding is the DSL API is
>now tightly coupled
>with SQL engine that I can not switch to another vender like Hibernate.
>
>As a user, I may prefer DSL API provided by JOOQ,  but have some
>performance concerns about
>underlying SQL engine and apt to use Hibernate, then I have to make a
>hard decision.
>This may not be a valid point to you. First JOOQ may have better
>performance than Hibernate(I saw
>reads about SQL performance mentioned in JOOQ document, which hints that
>JOOQ concerns much
>about performance). Second, I don't know if Hibernate can be solely used
>as a SQL engine.
>
>But decoupling the API from SQL engine provides potential flexibility for
>future, and might be easier
>to make the DSL API as a JSR.
>We have seen this much in DB. JPA is just a set of API. Mysql splits
>storage engine from server logic
>(Though the storage engine still couples with some server side logic like
>row locks). 
>
>Conclusion, besides the transaction management, I don't have too much
>concerns in using JOOQ in CloudStack now.
>I am glad to see after many years there is still a project actively
>working on solving DB problem in Java.
>
>
>> CRUD verbosity
>> ===========
>> > In this area, JPA does the right thing.
>> >
>> > Author author = new Author(...);
>> > JPAEntityManary.persist(author);
>> >
>> > The later one is more Java more OOP.
>> 
>> Compare this to jOOQ's CRUD features:
>> AuthorRecord author = ctx.newRecord(AUTHOR); author.store();
>> 
>> Or alternatively:
>> AuthorDao dao = ...
>> dao.insert(new Author());
>> 
>> Relevant sections in the manual are:
>> -
>> http://www.jooq.org/doc/3.2/manual/sql-execution/crud-with-
>> updatablerecords/
>> -
>> http://www.jooq.org/doc/3.2/manual/sql-execution/crud-with-
>> updatablerecords/simple-crud/
>> - http://www.jooq.org/doc/3.2/manual/sql-execution/daos/
>> 
>> Fluent APIs vs. SQL
>> ===============
>> I fully understand this concern. Using the jOOQ fluent API is not the
>>same as
>> writing SQL directly. But let me remind you of the concerns you are
>>having with
>> respect to database independence. By writing SQL directly (through JDBC,
>> through views or through stored procedures) you will not be able to
>>support
>> dozens of databases very easily. Both JPA and jOOQ solve this problem
>>quite
>> well. JPA abstracts SQL entirely, while jOOQ abstracts the subtle
>>differences,
>> only.
>> 
>> Fluent APIs vs. custom query building APIs
>> ================================ In addition to jOOQ's fluent API, there
>> is also a simpler, object-oriented SelectQuery model:
>> http://www.jooq.org/javadoc/latest/org/jooq/SelectQuery.html
>> 
>> The same applies for other types of statements (InsertQuery,
>>UpdateQuery,
>> etc.). Thus, compare this fluent API usage:
>> 
>> > create.selectFrom(BOOK)
>> >       .where(BOOK.PUBLISHED_IN.eq(2011))
>> >       .orderBy(BOOK.TITLE)
>> 
>> With this SelectQuery usage:
>> 
>> SelectQuery<Book> select = create.selectQuery(BOOK);
>> select.addCondition(BOOK.PUBLISHED_IN.eq(2011));
>> select.addOrderBy(BOOK.TITLE);
>> Result<Book> result = select.fetch();
>> 
>> This is also documented here:
>> 
>>http://www.jooq.org/doc/3.2/manual/sql-building/sql-statements/dsl-and-no
>>n-
>> dsl/
>> 
>> Conclusion
>> ========
>> I hope I could put jOOQ in a different light to you. If JPA is
>>sufficient for your
>> use-cases, then use JPA (or JPA+jOOQ). There are some problems that jOOQ
>> will never solve, which are solved very well in JPA. We have outlined
>>these
>> differences here:
>> http://www.hibernate-alternative.com
>> 
>> However, by using jOOQ, you not only gain a very high level of
>>typesafety and
>> thus an increase of productivity through the usage of jOOQ's code
>>generator
>> which helps you detect errors early, you also get access to a very rich
>>set of
>> service provider interfaces, which were off-topic in this discussion so
>>far. Some
>> examples:
>> 
>> ExecuteListeners for custom query execution lifecycle handling:
>> http://www.jooq.org/doc/3.2/manual/sql-execution/execute-listeners/
>> 
>> Schema and table mapping for multi-tenancy support:
>> 
>>http://www.jooq.org/doc/3.2/manual/sql-building/dsl-context/runtime-schem
>>a-
>> mapping/
>> 
>> Record mapping in order to provide custom mapping algorithms from jOOQ
>> records to your domain model:
>> http://www.jooq.org/doc/3.2/manual/sql-execution/fetching/pojos-with-
>> recordmapper-provider/
>> 
>> A query transformation listener that is still being worked on, allowing
>>for
>> arbitrary SQL transformation on the jOOQ AST. This can be very useful
>>for
>> features like row-level security.
>> 
>> As I said, we believe that there is currently no other software in the
>>Java
>> market that takes your SQL so seriously, and we're highly committed to
>> improve this even further in the near future.
>> 
>> Best Regards,
>> Lukas
>> 
>> 2013/11/27 Frank Zhang <Frank.Zhang@citrix.com>
>> 
>> > Hi Lukas:
>> >         Glad to see developer behind JOOQ here, I originally
>> > recommended using QueryDSL instead of JOOQ, there are some of my
>> > concerns:
>> >
>> > - Spring support. You know CloudStack is based on Spring IOC, the most
>> > compelling thing of Spring DB is its transaction management framework.
>> > QueryDSL has been integrated into Spring for two years. But there is
>> > only a simple page (
>> > http://www.jooq.org/doc/3.2/manual/getting-started/tutorials/jooq-with
>> > -spring/) demonstrating JOOQ and Spring,  however, the code just shows
>> > how to load JOOQ in IOC, it doesn't show any advanced feature of
>> > Spring DB for example declarative transaction management. If JOOQ is
>> > not compatible with Spring DB, then we loss a widely used feature.
>> >
>> > - It's not JPA based on. This might be an argument that JOOQ may claim
>> > as its biggest advantage. I agree JPA does have some bad thing(e.g.
>> > criteria API), but  the rest part is doing very well.
>> > The most important thing here is JPA is just API so I can choose
>> > underlying vendor by my preference. This non-lock-in feature is very
>> > appealing. For example, Hibernate has been proven by industry for 10
>> > years, I can fairly trust its quality. And vendor may have some
>> > advanced feature like secondary cache I may need someday.
>> > Instead, using JOOQ means I have to rely on its underlying
>> > implementation with no choice.
>> >
>> > You know almost all JPA vendors support different SQL dialects. And
>> > fluent API(or DSL) is not attractive to me. Frankly speaking, IMO, for
>> > insert/update/delete clause the fluent API makes thing unnecessary
>> > complex that you are writing something which is even more complicated
>> > than SQL, for example in JOOQ,
>> >
>> > == persistence ===
>> > create.insertInto(AUTHOR)
>> >       .set(AUTHOR.ID, 100)
>> >       .set(AUTHOR.FIRST_NAME, "Hermann")
>> >       .set(AUTHOR.LAST_NAME, "Hesse")
>> >       .newRecord()
>> >       .set(AUTHOR.ID, 101)
>> >       .set(AUTHOR.FIRST_NAME, "Alfred")
>> >       .set(AUTHOR.LAST_NAME, "Döblin");
>> >
>> > In this area, JPA does the right thing.
>> >
>> > Author author = new Author(...);
>> > JPAEntityManary.persist(author);
>> >
>> > The later one is more Java more OOP.
>> >
>> > === single table query ====
>> > Speaking of query, for single table query, fluent API is not
>> > attractive too. For example:
>> >
>> > Raw SQL:
>> >   SELECT * FROM BOOK
>> >    WHERE BOOK.PUBLISHED_IN = 2011
>> > ORDER BY BOOK.TITLE
>> >
>> > JOOQ:
>> > create.selectFrom(BOOK)
>> >       .where(BOOK.PUBLISHED_IN.eq(2011))
>> >       .orderBy(BOOK.TITLE)
>> >
>> >
>> > CloudStack search criteria built on JPA:
>> > Qeury<Book> q = new Qeury<Book>();
>> > q.add(Book_.PublishedIn. Op.eq, 2011); q.orderBy(Book_.title);
>> > List<Book> books = q.list();
>> >
>> > The last way is more Java for sure, people who even has no SQL
>> > knowledge can write the search.
>> >
>> > === multiple tables query ===
>> > The only place fluent API shining is querying multiple tables:
>> >
>> >   SELECT AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, COUNT(*)
>> >     FROM AUTHOR
>> >     JOIN BOOK ON AUTHOR.ID = BOOK.AUTHOR_ID
>> >    WHERE BOOK.LANGUAGE = 'DE'
>> >      AND BOOK.PUBLISHED > '2008-01-01'
>> > GROUP BY AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME
>> >   HAVING COUNT(*) > 5
>> > ORDER BY AUTHOR.LAST_NAME ASC NULLS FIRST
>> >    LIMIT 2
>> >   OFFSET 1
>> >      FOR UPDATE
>> >
>> > JOOQ:
>> >
>> > create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count())
>> >       .from(AUTHOR)
>> >       .join(BOOK).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
>> >       .where(BOOK.LANGUAGE.equal("DE"))
>> >       .and(BOOK.PUBLISHED.greaterThan("2008-01-01"))
>> >       .groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
>> >       .having(count().greaterThan(5))
>> >       .orderBy(AUTHOR.LAST_NAME.asc().nullsFirst())
>> >       .limit(1)
>> >       .offset(2)
>> >       .forUpdate();
>> >
>> > JPA does very badly in this area. However, you notice you are actually
>> > translating raw SQL into JOOQ DSL. In fact writing such a query is
>> > harder in JOOQ than in raw SQL, because you must not only know SQL
>> > knowledge but also know JOOQ dialects.  The only gain is type-safe. I
>> > know Java developers are used to static type too much, they are not
>> > willing to write any code that cannot be checked by compiler. Type
>> > safe is the reason that no ORM is perfect, and it can never be.
>> >
>> > In summary, I don't think dropping in any ORM can solve problem
>> > perfectly, if I did it, I would do:
>> >
>> > - Using JPA based framework.
>> > - building persistent interface(create/update/delete) and single table
>> > search criteria using JPA
>> > - for multiple tables query, either using JPA JPQL(if you don't mind
>> > type
>> > safe) or dropping in some fluent API framework if you can not stand
>> > for any type unsafe thing.
>> >
>> >
>> >
>> > > -----Original Message-----
>> > > From: Lukas Eder [mailto:lukas.eder@gmail.com]
>> > > Sent: Tuesday, November 26, 2013 3:58 AM
>> > > To: dev@cloudstack.apache.org
>> > > Subject: Re: persistence layer
>> > >
>> > > Dear CloudStack developers,
>> > >
>> > > This thread has caught my attention and I thought I might chime in
>> > > and
>> > give
>> > > you some background information about jOOQ, JDBC, RDBMS in general
>> > > (I work for Data Geekery, the company behind jOOQ). I've already had
>> > > the pleasure to talk to Darren on the jOOQ User Group and on the
>>phone.
>> > >
>> > > Here are some answers to open questions I've seen in this thread:
>> > >
>> > > 2013/11/26 Alex Huang <Alex.Huang@citrix.com>
>> > >
>> > > > Has anyone actually tried dropping in a different jdbc driver and
>> > > > see if CS can use another DB?  I don't think the current CS DB
>> > > > layer prevents anyone from doing that.
>> > > >
>> > > > This is different from MariaDB which, as othes have pointed out,
>> > > > is drop-in replacement for MySQL.  I'm talking about stuff like
>> > > > derby or sqlserver or oracle or db2.
>> > > >
>> > >
>> > > MariaDB and MySQL are diverging quickly, as Oracle invests quite
>> > > some development efforts into MySQL. While the drop-in replacement
>> > > argument is valid right now, it might not be two years from now.
>> > >
>> > > In general, SQL dialects are very different when it comes to the
>> > subtleties of
>> > > syntax or feature sets. Since you're comparing MySQL with Derby, SQL
>> > Server,
>> > > Oracle, or DB2, let me give you some ideas:
>> > >
>> > > - MySQL has a lot of vendor-specific clauses that no one else has
>>(e.g.
>> > ON
>> > > DUPLICATE KEY UPDATE)
>> > > - MySQL bends the SQL syntax and accepts what is otherwise illegal
>> > syntax (e.g.
>> > > GROUP BY semantics [1])
>> > > - MySQL doesn't correctly implement the SQL standard NOT IN
>> > > semantics [2]
>> > > - Derby and DB2 (prior to version 9.7) are extremely type-safe. For
>> > instance,
>> > > CAST(NULL AS INT) and CAST(NULL AS VARCHAR) are two entirely
>> > > different things. This can lead to tedious work when binding null as
>> > > a bind
>> > variable. Some
>> > > background info [3]
>> > > - DB2 has a lot of peculiarities when it comes to memory management
>> > > of VARCHAR [4]
>> > > - Case-sensitivity of schema, table, and column names is an eternal
>> > hassle
>> > > between RDBMS
>> > > - JDBC drivers implement things very differently in some areas.
>> > > Fetching
>> > an
>> > > inserted ID is really a pain.
>> > >
>> > > [1]: http://blog.jooq.org/2012/08/05/mysql-bad-idea-384/
>> > > [2]:
>> > >
>> > http://blog.jooq.org/2012/01/27/sql-incompatibilities-not-in-and-null-
>> > values/
>> > > [3]:
>> > http://blog.jooq.org/2011/08/31/rdbms-bind-variable-casting-madness/
>> > > [4]: http://stackoverflow.com/q/9234021/521799
>> > >
>> > > If you want cross-database support, these things show that you
>> > > should
>> > really
>> > > consider moving away from using plain JDBC and use an abstraction
>> > > that
>> > will
>> > > take care of these incompatibilities for you. You might be choosing
>> > between
>> > > Hibernate and jOOQ (or both) depending on the way you plan to
>> > > interact
>> > with
>> > > your RDBMS. Our point of view is illustrated here:
>> > > http://www.hibernate-alternative.com
>> > >
>> > > Some larger jOOQ customers currently use jOOQ with Oracle, Sybase,
>> > > SQL Server, MySQL, and H2 from the same application.
>> > >
>> > > > Frank Zhang Fri, 22 Nov 2013 10:42:09 -0800 I recommend QueryDSL.
>> > > > Having a quick look at JOOQ, it's very similar to QueryDSL.
>> > > > QueryDSL has been integrated into Spring for 2 years, and JOOQ
>> > > > haven't
>> > > had
>> > > > official doc for Spring.
>> > > > Besides Sql, QueryDSL also gets fair credit on manipulating NoSql
>> > > > which
>> > > is an
>> > > > additional plus.
>> > >
>> > > jOOQ and Spring work together quite nicely, even if there is not an
>> > "official"
>> > > affiliation between the two stacks:
>> > >
>> > > -
>> > > http://www.jooq.org/doc/3.2/manual/getting-started/tutorials/jooq-wi
>> > > th-
>> > > spring/
>> > > -
>> > > http://blog.jooq.org/2012/09/19/a-nice-way-of-using-jooq-with-spring
>> > > /
>> > > - http://blog.uws.ie/2013/04/using-jooq-with-spring-transactions/
>> > > - http://stackoverflow.com/q/4474365/521799
>> > >
>> > > We're aware of QueryDSL offering SQL and NoSQL support through a
>> > > single
>> > API.
>> > > In our opinion, such greater unification attempts will always come
>> > > with
>> > an
>> > > impedance mismatch at some point. In other words, you'll be losing
>> > > on SQL functionality in favour of greater standardisation /
>>abstraction.
>> > > From our experience with jOOQ, SQL standardisation is already a very
>> > > hard problem. NoSQL databases all work fundamentally differently.
>> > > The added complexity by supporting NoSQL in the same API as SQL
>> > > databases is
>> > significant.
>> > >
>> > > Of course, these things depend on whether replacing MySQL for any
>> > > NoSQL database in CloudStack is really a desired, near-term option.
>> > >
>> > > ----
>> > > I'll be following this thread for another while and I'm more than
>> > > happy
>> > to
>> > > answer any questions you may have related to jOOQ, SQL, JDBC, etc.
>> > >
>> > > Best Regards,
>> > > Lukas
>> >


Mime
View raw message