Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Keetron
Sep 26, 2008

Check out my enormous testicles in my TFLC log!

i vomit kittens posted:

Does anyone have advice on how to get Spring Boot to properly store lists in a Postgres table?

You can be like us and just use the jsonb type of Postgres and just dump the json in a cell and hey, it is searchable as well!
Of you know, don't be like us and use a relational database as it is meant and do your json dumping in cassandra or mongo or some other shite

Adbot
ADBOT LOVES YOU

Soricidus
Oct 21, 2010
freedom-hating statist shill

Keetron posted:

You can be like us and just use the jsonb type of Postgres and just dump the json in a cell and hey, it is searchable as well!
Of you know, don't be like us and use a relational database as it is meant and do your json dumping in cassandra or mongo or some other shite

Elasticsearch, the database of champions

ChickenWing
Jul 22, 2010

:v:

DELETE CASCADE posted:

just use a native sql query because hql hibernate is trash

Volguus
Mar 3, 2009
I strongly disagree with that assertion (that hibernate is trash). It can, however, generate in some cases sub-optimal queries. If that's 90% of your use case, then definitely hibernate (or probably any orm) is not appropriate for you and your app. But for 99% of the cases, of the apps out there, the dumb CRUD apps, hibernate saves a shitload of time as it really doesn't do anyone any favors to have to write "select bar from foo where id=5" 100 times.

Profile your app and replace those badly generated hibernate queries (with native sql if you have to) and you will come out on top in the end.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Volguus posted:

I strongly disagree with that assertion (that hibernate is trash). It can, however, generate in some cases sub-optimal queries. If that's 90% of your use case, then definitely hibernate (or probably any orm) is not appropriate for you and your app. But for 99% of the cases, of the apps out there, the dumb CRUD apps, hibernate saves a shitload of time as it really doesn't do anyone any favors to have to write "select bar from foo where id=5" 100 times.

Profile your app and replace those badly generated hibernate queries (with native sql if you have to) and you will come out on top in the end.

Yeah, it's super easy to use a native query with hibernate for one off stuff you need to optimize.

Also you guys are triggering my DBA PTSD with these pseudo-many-to-many relationships stored as an array converted to a string in a column. Please, for the love of god, don't do things like that.

adaz
Mar 7, 2009

JDK 14 is out officially.

I think I might have to play around with the new packaging tool for building native installers for jars. It's of moderate use especially for random console apps built to containers but still kind of cool. Only other thing that is of interest I saw is the new async JFR stuff which will be nice especially once it gets integrated into some of the APM toolsets out there.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

adaz posted:

JDK 14 is out officially.

I think I might have to play around with the new packaging tool for building native installers for jars. It's of moderate use especially for random console apps built to containers but still kind of cool. Only other thing that is of interest I saw is the new async JFR stuff which will be nice especially once it gets integrated into some of the APM toolsets out there.

JEP 358: Helpful null pointer exceptions.

The future is now!

1337JiveTurkey
Feb 17, 2005

Also a direct memory access API which is supposed to be much better than NIO memory channels. I’ve been working on some stuff that could use shared access to a big pile of off-heap structs and this should do quite nicely.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Sounds cool, can't wait until 2030 to use it in our tools because people are dragging their feet getting off of Java 6, much less to 11...

adaz
Mar 7, 2009

carry on then posted:

Sounds cool, can't wait until 2030 to use it in our tools because people are dragging their feet getting off of Java 6, much less to 11...

This is some bleak poo poo. is there even anyone who releases security patches for 6?

Also I had forgotten, but a coworker reminded me, 14 is a LTS release too! :toot:

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

adaz posted:

This is some bleak poo poo. is there even anyone who releases security patches for 6?

Also I had forgotten, but a coworker reminded me, 14 is a LTS release too! :toot:

Is it? I thought 17 was the next LTS release. Oracle doesn't show 14 as LTS on their docs https://www.oracle.com/java/technologies/java-se-support-roadmap.html

adaz
Mar 7, 2009

carry on then posted:

Is it? I thought 17 was the next LTS release. Oracle doesn't show 14 as LTS on their docs https://www.oracle.com/java/technologies/java-se-support-roadmap.html

ah yeah you're right. I thought it was every 18 months but it literally says it righ there - every 3 years is an LTS.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

adaz posted:

This is some bleak poo poo. is there even anyone who releases security patches for 6?

I'm sure Oracle will if you shell out the $$$

ivantod
Mar 27, 2010

Mahalo, fuckers.

adaz posted:

ah yeah you're right. I thought it was every 18 months but it literally says it righ there - every 3 years is an LTS.

I wish it were 18 months, so I wouldn't have to wait until Java 17 for multiline strings... because that was added in Java 13 and the current LTS version is 11.

ChickenWing
Jul 22, 2010

:v:

Style question (:can:)

SonarLint says any more constructor parameters than 7 is a code smell. Does that not apply to POJOs/Data classes? Is there another pattern that one should use in those cases (I saw the Builder pattern suggested). Should said class just be composed of smaller objects? Should I dehumanize and face to the fact that my enterprise java server is going to be full of said code smells because there are too many things doing too many things?

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?
I wouldn't personally wrinkle my nose at a POJO class with a lot of fields, whether they are all constructor parameters or not.

I suspect the Sonar rule is meant for "real" classes, where it would definitely signify a class that is growing too big (i e does too many things).

That said, I guess it's for a POJO it's comparable to how tables with a lot of columns are traditionally discouraged in relational databases. It works fine in practice but it's "better" to spread the data over several relations, for reasons mostly academic.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

There are certainly possible occasions where having one constructor with tons of parameters is really the closest modeling of the underlying data. I just wrote a data class that holds values for all the possible properties that can be set on a resource adapter that can be configured, and I wound up with 40 parameters, but there's no real way to break it up.

Pedestrian Xing
Jul 19, 2007

I like the fluent pattern for POJOs with a lot of fields. Lombok and IntelliJ can both generate them.

Splinter
Jul 4, 2003
Cowabunga!
I would think a Builder would be the way to go if you have that many constructor parameters. Fluent setters is an improvement over trying to get the ordering of that many constructor parameters correct, but that leaves open the possibility that a client won't set everything that needs to be set before the object is used. Builder gives you the fluent benefit of not having to get the constructor parameter ordering correct, and can ensure an object is in a valid state before it can be used. It also allows for making the object immutable, which isn't possible using a fluent setter approach.

Pedestrian Xing
Jul 19, 2007

Splinter posted:

I would think a Builder would be the way to go if you have that many constructor parameters. Fluent setters is an improvement over trying to get the ordering of that many constructor parameters correct, but that leaves open the possibility that a client won't set everything that needs to be set before the object is used. Builder gives you the fluent benefit of not having to get the constructor parameter ordering correct, and can ensure an object is in a valid state before it can be used. It also allows for making the object immutable, which isn't possible using a fluent setter approach.

This is very true - fluent pattern does tend to make state validation difficult.

Side note: I've started using JSR 305 annotations in all my new code and really like them. Specifically, I'm using Spring's @Nullable/@NonNull meta-annotations.

Pedestrian Xing fucked around with this message at 20:35 on Mar 19, 2020

adaz
Mar 7, 2009

ChickenWing posted:

Style question (:can:)

SonarLint says any more constructor parameters than 7 is a code smell. Does that not apply to POJOs/Data classes? Is there another pattern that one should use in those cases (I saw the Builder pattern suggested). Should said class just be composed of smaller objects? Should I dehumanize and face to the fact that my enterprise java server is going to be full of said code smells because there are too many things doing too many things?

1. As other suggested lombok is the _easiest_ way around this and for pure POJOs i think it's fine. @requiredArgsConstructor handles _most_ of my validation concerns for simple pojos

2. You can break down the data model into a larger nested class but this does has performance penalties when hydrating your models if you're pulling from a datastore and relying on JPA. It's also not a terrible idea though if hte data model makes sense. However there are certainly valid entities that have more than 7 properties to them and furher decomposition would just ultimately hurt your understanding.

3. be like me and beg for kotlin style data classes in java

4. if you need ot do a lot of validation and complex logic builders are legit and you should do that.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

adaz posted:

1. As other suggested lombok is the _easiest_ way around this and for pure POJOs i think it's fine. @requiredArgsConstructor handles _most_ of my validation concerns for simple pojos

2. You can break down the data model into a larger nested class but this does has performance penalties when hydrating your models if you're pulling from a datastore and relying on JPA. It's also not a terrible idea though if hte data model makes sense. However there are certainly valid entities that have more than 7 properties to them and furher decomposition would just ultimately hurt your understanding.

3. be like me and beg for kotlin style data classes in java

4. if you need ot do a lot of validation and complex logic builders are legit and you should do that.

Lombok also has an @Builder annotation that makes it super simple: https://projectlombok.org/features/Builder

adaz
Mar 7, 2009

RandomBlue posted:

Lombok also has an @Builder annotation that makes it super simple: https://projectlombok.org/features/Builder

:gizz: not sure how I missed this but this is so so so nice.

Lombok is probably my singel favorite java library so many great gems.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I'm going to say that "generate the constructor instead of writing it yourself" is not actually a good solution to "my linter is complaining about constructors with way too many parameters". The problems with constructors that have too many parameters are on the usage side rather than the writing side, which generating your constructor doesn't help with at all.

Builders are good though. Using something like AutoValue to generate the builder boilerplate is excellent. Try to stay away from lombok unless you like your project to be incompatible with every bit of Java tooling that the lombok developers haven't specifically made a customized version for.

Jabor fucked around with this message at 23:02 on Mar 19, 2020

ChickenWing
Jul 22, 2010

:v:

Cool beans, yeah that's about the response I figured.

I, too, have suffered the pain that is trying to integrate lombok with things that lombok does not want to be integrated with yet - for now, I'll stick with having intellij autogenerate stuff for me.

Soricidus
Oct 21, 2010
freedom-hating statist shill
so, estimating memory size of objects

there are like a billion libraries to do it, but I am struggling to find one that has ever been updated to work with java 9+. they literally all try to make fields accessible in internal jdk stuff and life's too short to write a billion --add-opens

I know it's impossible to be accurate, etc. I just want a rough idea of whether a change is decreasing memory usage measurably. I know how to do it by inspecting a heap dump in visualvm or w/e but that's a huge pita compared to if i could just System.out.println(size of some object), like all these libraries offer to let me do if i port my code back to java 8.

any suggestions?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
It's not clear what question you're asking.

If you want to know how big a particular object is, use Instrumentation.getObjectSize(). If you want to know how a big a particular object and every other object that it's keeping alive is ... that's not really possible for any library to answer in general terms. Answering that question accurately requires a deep understanding of data and control flow in your application.

I'm sure all these tools do a great job of spitting out numbers that are kind of meaningless and not very helpful for actually optimizing things.

Soricidus
Oct 21, 2010
freedom-hating statist shill
yes, like I said, I know it's impossible to be accurate in the general case.

Let me be more specific then: I want the result of walking the reference graph from a given object and summing the sizes of each object encountered, while keeping a set of visited objects to avoid cycles. Please assume that I have thought about this in the context of my application and determined that it will give me a useful number.

Plenty of tools exist to do this, but all the ones I've tried fail because they hit an object that isn't exported by some module, try to get its fields to follow their references, and die because the JVM doesn't let you do that any more.

e: for now it looks like the even less reliable "force GC, measure heap size, create object, force GC again, measure heap size again" approach is giving tolerable results for my specific use case.

Soricidus fucked around with this message at 17:09 on Mar 26, 2020

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
I read that you can dump your database structure into an XML file and then generate jOOQ classes from that. How do you do it? Or should I just check in the generated classes to version control?

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Wheany posted:

I read that you can dump your database structure into an XML file and then generate jOOQ classes from that. How do you do it? Or should I just check in the generated classes to version control?

Nevermind, I'm just checking in the generated classes, that's what I've always done in other projects too, I'm not sure why I thought I wouldn't do that now

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?
I would check in the generated code, yeah.

My team took the other route, which keeps the repo clean but gives us a slower build. Our product is micro-services in Dockers, and the Gradle build will spin up an instance of our Postgres docker and re-generate the DB classes every build. I really don't like it because it adds 7-12 seconds to every build which we didn't really need. (If you keep a "master database" running somewhere in your CI machinery, this would take just 1-2 seconds, but that would be one weird CI for a container based build...)

It is slightly safer though, because it won't fail in odd ways if someone changes the DB structure and forgets to re-run the jOOQ generation task and check in the new generated code.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Hippie Hedgehog posted:

I would check in the generated code, yeah.

My team took the other route, which keeps the repo clean but gives us a slower build. Our product is micro-services in Dockers, and the Gradle build will spin up an instance of our Postgres docker and re-generate the DB classes every build. I really don't like it because it adds 7-12 seconds to every build which we didn't really need. (If you keep a "master database" running somewhere in your CI machinery, this would take just 1-2 seconds, but that would be one weird CI for a container based build...)

It is slightly safer though, because it won't fail in odd ways if someone changes the DB structure and forgets to re-run the jOOQ generation task and check in the new generated code.

Yeah, slowing down the build is annoying but wasting 30-60+ minutes trying to figure out why something is broken because someone forgot to update the generated code is worse.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
No-one cares about your CI builds being ten seconds longer, and your developer incremental builds shouldn't be rebuilding the db classes anyway because it can see that you haven't changed the files that go into generating them.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Jabor posted:

No-one cares about your CI builds being ten seconds longer, and your developer incremental builds shouldn't be rebuilding the db classes anyway because it can see that you haven't changed the files that go into generating them.

Yeah, my poo poo takes at least 10 minutes right now. I'd easily tack on another 20 seconds to avoid poo poo failing from manual generation let alone having PRs including generated code changes.

CPColin
Sep 9, 2003

Big ol' smile.
I always liked regenerating all the generated code and catching the devs red-handed who either didn't commit a change to the definitions or did and didn't regenerate the associated class.

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

Jabor posted:

No-one cares about your CI builds being ten seconds longer, and your developer incremental builds shouldn't be rebuilding the db classes anyway because it can see that you haven't changed the files that go into generating them.

That's easy enough to say, but can you write a Gradle configuration that actually realizes that up-to-date check?

IIRC, the problem was yes, Gradle keeps good track of the input (SQL) files and sees that they're unchanged, but there was no way for it to track the up-to-date-ness of the outputs, when the outputs are Docker images. Or something like that, ask our build engineer...

Hughlander
May 11, 2005

CPColin posted:

I always liked regenerating all the generated code and catching the devs red-handed who either didn't commit a change to the definitions or did and didn't regenerate the associated class.

I've done that as a post-build asynchronous test. It wasn't critical path for anything but would still be marked as a test failure and flag the commit.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Hippie Hedgehog posted:

That's easy enough to say, but can you write a Gradle configuration that actually realizes that up-to-date check?

IIRC, the problem was yes, Gradle keeps good track of the input (SQL) files and sees that they're unchanged, but there was no way for it to track the up-to-date-ness of the outputs, when the outputs are Docker images. Or something like that, ask our build engineer...

Is there something special about docker images that prevents you from comparing file modification times?

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

Jabor posted:

Is there something special about docker images that prevents you from comparing file modification times?

I have no idea how the Docker daemon stores images, presumably they're files somewhere. I think Gradle doesn't use timestamps but hashes to check file up-to-date-ness. Especially for outputs, time stamps are not very useful, and even for inputs, you risk re-building files that were touched but not changed, which is pretty common when you're working in an IDE and/or with Git.

Adbot
ADBOT LOVES YOU

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Okay. So why can't you do that for a docker image? It's ultimately a file on a disk!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply