Live data from Hacker News

Problems with JPA/Hibernate

stemlaur.com

181–190 of 195 posts

Re: Problems with JPA/Hibernate

#181

Earlier quoted context omitted.

I don’t think my point was sloppily written, but perhaps you misunderstood it. JPA is conceptually incapable of automatically utilising the structure of the underlying database (despite the fact that the database structure is actually dynamic), so it makes up for it by requiring you to write these huge entity models which declare - and duplicate - that structure. You effectively “throw away” the database structure be…

I might start to get what you are hinting at. Still the > JPA is conceptually incapable of automatically utilising the structure of the underlying database (despite the fact that the database structure is actually dynamic), so it makes up for it by requiring you to write these huge entity models which declare - and duplicate - that structure. You effectively “throw away” the database structure because you have to rew…

It’s fine to pick at my comments, that’s what HN is for!

I accept that when I said “you get to throw away...” I was being a bit glib. I meant that we write the DDL, run it, and despite it being stored in the database as structure, that DDL is never used again by JPA and you have to rewrite it in annotations.

I thought lack of knowledge about indexes was an issue because I had a use case where the generated SQL was (very) sub optimal and thought it was due to an assumption made by JPA, but someone pointed out that maybe I used a Set instead of a List. I still think that’s stupid (it’s hardly fixing the “impedance mismatch” when which is the very purpose of JPA), but might not be index related. That said, knowledge about indexes does impact the design of handwritten queries and JPA doesn’t have that; JPA queries can be overly complex, and even pathological, so again I think the point holds up.

In my defence I was listing a lot of issues. I feel like I could write a book on the problems with JPA but all I had was this tiny box on my phone.

In terms of scaring people off, that is definitely my intent. There are lots of great ways to get Java talking to SQL, many linked to in this thread, and IMO the majority of developers would be better off choosing almost any alternative over JPA.

Re: Problems with JPA/Hibernate

#182

Earlier quoted context omitted.

JPA is OK (but only OK) if you don’t have anything other than JPA accessing the database but in our largest application (1,000+ tables) this was never going to be the case. We had plenty of experience with database design, that’s not the problem. But we found even in simple applications with a dozen tables, the generated SQL was suboptimal. For example, to delete the children of a parent row resulted in a DELETE stat…

How do you get 75% fewer LOC without using JPA or Hibernate? All I have to do to create a new table is define a class with some attributes and the corresponding SQL migration, I don't even have to annotate anything. To create a new row I just do new Table(attr1: expression1, attr2: expression2).save() and I am done. Compare that to the usual mess of writing down the same column name four times with raw SQL (1. to ref…

So now you have code in Gorm generating DDL and JPA code? In terms of the compiled LOC, doesn’t this add even more code? Not to mention another dependency to maintain.

Anyway - I’m definitely not advocating for raw JDBC, there are lots of libraries you can use to reduce the complexity of the integration with the database, it’s just that JPA is not (IMO) one of them.

One thing I don’t understand about your comment it “the usual mess of writing down the column name four times with raw SQL” - when is this necessary? ’update table set column=? where key=?’ has no duplicate names. Can you give an example?

I’m intrigued by how your solution to JPA’s verbosity problem is to add another layer, while mine is to remove one!

Re: Problems with JPA/Hibernate

#183

Earlier quoted context omitted.

Pretty sure I would have used a list, but making the Java interface ordered surely doesn’t change the semantics of the underlying relation?!

> Pretty sure I would have used a list, but making the Java interface ordered surely doesn’t change the semantics of the underlying relation?! Yeah, it seems a little bonkers on first glance and I haven't ever dug in to see if there was a justifiable reason or not. IIRC, if you just need ordering, you could just use an SortedSet. I think technically lists are for when you need ordering and duplicates.

Yeah it is bonkers! Not just at first glance. The fact that the SQL integration for the child object behaves differently based on the kind of collection used in the parent is exactly the kind of unintuitive behaviour that drove me nuts.

There are so many rules to remember for something that is supposed to make SQL integration natural.

Re: Problems with JPA/Hibernate

#184
post #40

Earlier quoted context omitted.

> Personally, I'm a fan of giving everything a random UUID, because it's more flexible Unless of course, you're using a relational database like OP and incur a performance hit from using a UUID as your primary key. Additionally, they're not sortable like autoinc id's. I've always wanted to try out Twitter's Snowflake ID [1] algorithm to get around this, but it requires requires using something like Zookeeper. I've se…

> they're not sortable like autoinc id's. ksuid https://segment.com/blog/a-brief-history-of-the-uuid/ Using DB autogenerated IDs risks that nightmare situation I've seen in more than one organization I've worked with: the IDs "leak" and become actual identifiers, in perpetuity, for the related entity. Now you can no longer renumber your table, and if you dump and restore you get all new IDs.

Your comment seems to conflate autogenerated IDs like MySQL AUTO_INCREMENT or PostgreSQL SERIAL with internal row IDs. Autogenerated keys are set on insert if you don't provide a value. After that they are stable. (And very popular, too.)

The case you describe sounds like using Oracle ROWID as a key, which I suppose people do as a hack to get around schema problems instead of fixing the schema. [1] That's an exceptionally bad idea.

[1] https://docs.oracle.com/cd/B19306_01/server.102/b14200/pseud...

Re: Problems with JPA/Hibernate

#185

Earlier quoted context omitted.

I might start to get what you are hinting at. Still the > JPA is conceptually incapable of automatically utilising the structure of the underlying database (despite the fact that the database structure is actually dynamic), so it makes up for it by requiring you to write these huge entity models which declare - and duplicate - that structure. You effectively “throw away” the database structure because you have to rew…

It’s fine to pick at my comments, that’s what HN is for! I accept that when I said “you get to throw away...” I was being a bit glib. I meant that we write the DDL, run it, and despite it being stored in the database as structure, that DDL is never used again by JPA and you have to rewrite it in annotations. I thought lack of knowledge about indexes was an issue because I had a use case where the generated SQL was (v…

I still think your experience is a bit on the extreme side but I'll still admit you've got me thinking: not because I've seen ORM causing much problems (I can use them just fine with indexes and custom SQL) but because maybe there is a better way.

Last I read up on MyBatis is probably >10 years ago and IIRC at that point it seemed like a manifestation of what the Rails guys teased us with:

  
    
    
  
but I'll admit:

- I've been wrong before

- things might have changed in 10 years

- I've always known there were cases for something else but maybe I should adjust my threshold

For anyone else who reads this, just be aware that many smart people are happily using JPA. :-)

Re: Problems with JPA/Hibernate

#186

Earlier quoted context omitted.

> they're not sortable like autoinc id's. ksuid https://segment.com/blog/a-brief-history-of-the-uuid/ Using DB autogenerated IDs risks that nightmare situation I've seen in more than one organization I've worked with: the IDs "leak" and become actual identifiers, in perpetuity, for the related entity. Now you can no longer renumber your table, and if you dump and restore you get all new IDs.

Your comment seems to conflate autogenerated IDs like MySQL AUTO_INCREMENT or PostgreSQL SERIAL with internal row IDs. Autogenerated keys are set on insert if you don't provide a value. After that they are stable. (And very popular, too.) The case you describe sounds like using Oracle ROWID as a key, which I suppose people do as a hack to get around schema problems instead of fixing the schema. [1] That's an exceptio…

Can you clarify how autogenerated keys are different from an autoincrement id column? In my experience, the autogenerated keys are built on top of auto-increment columns. Of course, if you use a stored procedure or something to generate a value, then you're just using a unique ID, same as anything else, but making your system dependent on the DB, which isn't awesome if you have a distributed system with replication and all that.

Re: Problems with JPA/Hibernate

#187

Earlier quoted context omitted.

How do you get 75% fewer LOC without using JPA or Hibernate? All I have to do to create a new table is define a class with some attributes and the corresponding SQL migration, I don't even have to annotate anything. To create a new row I just do new Table(attr1: expression1, attr2: expression2).save() and I am done. Compare that to the usual mess of writing down the same column name four times with raw SQL (1. to ref…

So now you have code in Gorm generating DDL and JPA code? In terms of the compiled LOC, doesn’t this add even more code? Not to mention another dependency to maintain. Anyway - I’m definitely not advocating for raw JDBC, there are lots of libraries you can use to reduce the complexity of the integration with the database, it’s just that JPA is not (IMO) one of them. One thing I don’t understand about your comment it…

I think he is talking about upsert

Re: Problems with JPA/Hibernate

#188

I solve Hibernate problems by using jOOQ instead. The migration more than paid off the couple times I did it.

How do you solve storing/updating/removing child entities of another entity (which also may be a child of another entity) effectively? I use jOOQ as well, but mostly only for the reading part. For the above case, I still use Hibernate, as I've yet to find an efficient way to do it in jOOQ.

My models have always been fairly simple with not too many levels of child entities. I contain all the logic for a given entity in a single class (where I hand write the code to update related entities). I do have to keep my fingers crossed that nobody will implement similar-but-wrong logic in some other spot in the codebase. The 1:1 mapping between entities and classes to CRUD helps to some degree.

Re: Problems with JPA/Hibernate

#189
post #8

The underlying problem is one of O-R impedance mismatch. Going full SQL and getting rid of the ORM is a possible answer, but it has tradeoffs and is not a silver bullet. It might mean re-creating from scratch an in-house, bug-ridden ORM, or ditching OOP idioms from your language, or both. The author of TFA seems to be going through one of the stages described in "ORM is the Vietnam of Computer Science", an article th…

I don't believe that to be the case. The vast majority of applications built on top of ORMs design databases so that they are easy to map to. Sure, as soon as you access a database that wasn't designed for the ORM you run into trouble but this is an all or nothing problem. Getting rid of the ORM where it works doesn't actually provide you with a benefit.

> Sure, as soon as you access a database that wasn't designed for the ORM you run into trouble

Don't you mean the reverse? A relational database is never designed "for the ORM" -- ORMs are designed (sometimes poorly, sometimes better) for some databases. The object-relational impedance mismatch problem is well known in software engineering for a reason: OOP and relational databases weren't designed with each other in mind, and in fact, "fight against each other" in many ways. This is the starting point of the Vietnam article -- you can disagree with the analogy, but the impedance mismatch is very real.

Re: Problems with JPA/Hibernate

#190

Earlier quoted context omitted.

Your comment seems to conflate autogenerated IDs like MySQL AUTO_INCREMENT or PostgreSQL SERIAL with internal row IDs. Autogenerated keys are set on insert if you don't provide a value. After that they are stable. (And very popular, too.) The case you describe sounds like using Oracle ROWID as a key, which I suppose people do as a hack to get around schema problems instead of fixing the schema. [1] That's an exceptio…

Can you clarify how autogenerated keys are different from an autoincrement id column? In my experience, the autogenerated keys are built on top of auto-increment columns. Of course, if you use a stored procedure or something to generate a value, then you're just using a unique ID, same as anything else, but making your system dependent on the DB, which isn't awesome if you have a distributed system with replication a…

I might have missed something upthread but autogenerated keys to me just mean that the key is somehow generated automatically for you rather than using a natural key like social security number (SSAN) when inserting rows. Autoincrement IDs are one way of autogenerating a key that delegates generation to the DBMS server.

To expand on this, there are three common approaches to create automatic keys in SQL applications.

1.) Generate it in the application itself. You can make UUIDs yourself with a simple call in most languages. Ensuring uniqueness is your problem--to generate integers, for example, you'll need some sort of coordination if there's more than one application thread.

2.) Generate it from a SEQUENCE. Sequences are database-side key generators that hand back a unique sequence number from a block of available sequence numbers when you call for the next number. Uniqueness is pretty much guaranteed since numbers come from the shared database server. This approach is popular in PostgreSQL and Oracle.

3.) Generate it from an auto-increment column, such as MySQL AUTO_INCREMENT columns. Auto-increment columns generate the key server-side at insert time. Uniqueness is guaranteed, but you can't see the key until it has been inserted. If you need to know the key for follow-on INSERT or UPDATE commands you have to select it back using LAST_INSERT_ID(). [1] Auto-increment keys are popular in MySQL.

ORMs like Hibernate JPA tend to provide all of these as choices. I don't use ORMs much myself hence can't comment much on the details.

[1] https://dev.mysql.com/doc/refman/8.0/en/information-function...

Post reply on HN