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
Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
So I'm trying to write a spring controller that will add a recipe to my sql db. Ingredients are unique and don't contain a recipeId and its all tied together in a junction table that looks kinda like this:
code:
junction table

idJunction	idRecipe	idIngredient	idUnits	amount
1		1		1		3		1
2		1		2		2		16
3		2		3		2		8
4		1		3		2		4

Assuming I've got all my entities set up correctly how much of the work can I expect spring to do wrt to populating the junction table? Will I need to save to the junctionRepository?

edit: Of course I will, because the junction entry has the prep notes and quantities for the ingredients.

If each ingredient is coming back from the form with notes about measurement, quantity and prep notes could I make those transient properties in ingredients so that while they're there to be entered into the junction table they're not stored as part of the main ingredient entry or is that going to screw everything up?

edit edit: Doing that is giving me this error Inferred type 'S' for type parameter 'S' is not within its bound; should extend 'com.recipeproject.recipeproject.models.Junction'

My add junction row looks like this if its any help:

List<Ingredient> tempList = new ArrayList<>();
for (Ingredient ingredient: tempList) {Ingredient ingredient1 = new Ingredient();
junctionRepository.save(newRecipe, ingredient, ingredient.getMeasurement(), ingredient.getAmount(), ingredient.getPrepNotes() );

Guildenstern Mother fucked around with this message at 00:56 on Jan 9, 2022

Adbot
ADBOT LOVES YOU

Pedestrian Xing
Jul 19, 2007

Guildenstern Mother posted:

So I'm trying to write a spring controller that will add a recipe to my sql db. Ingredients are unique and don't contain a recipeId and its all tied together in a junction table that looks kinda like this:
code:
junction table

idJunction	idRecipe	idIngredient	idUnits	amount
1		1		1		3		1
2		1		2		2		16
3		2		3		2		8
4		1		3		2		4

Assuming I've got all my entities set up correctly how much of the work can I expect spring to do wrt to populating the junction table? Will I need to save to the junctionRepository?

Is this using Spring Data JPA? If so, I think you would set up your IngredientJunction (entity) class with the id field as a standard ID and then recipe/ingredient/unit would each be a field of that entity type. Things like amount and prep notes would be standard @Column fields. You would set the relation up using @ManyToOne/@OneToMany annotations. At save time, it might look like this:
code:
var junctionsToSave = new ArrayList<IngredientJunction>();
for (IngredientRequest ingredient : recipeRequest.getIngredients()) {
	junctionsToSave.add(new IngredientJunction(newRecipe, ingredientEntity, ingredient.getMeasurement(), ingredient.getAmount(), ingredient.getPrepNotes()));
}
ingredientJunctionRepository.saveAll(junctionsToSave);

Guildenstern Mother posted:

If each ingredient is coming back from the form with notes about measurement, quantity and prep notes could I make those transient properties in ingredients so that while they're there to be entered into the junction table they're not stored as part of the main ingredient entry or is that going to screw everything up?

A general best practice is to use DTO classes for things like requests and responses - you don't want to pass entities around. It can break in a lot of subtle ways as well as setting you up for unintended data disclosure.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
That's pretty much how I have the entity set up in spring. Let me just link (what I think is) all the relevant code. It currently has the @Transient fields in the ingredient model.
https://pastebin.com/b4nzXz0i
I'm wondering if I've got something obvious that's giving me the "'S' for type parameter 'S' is not within its bound; should extend 'com.recipeproject.recipeproject.models.Junction'" error, like a bad class/repository set up.

Pedestrian Xing posted:

A general best practice is to use DTO classes for things like requests and responses - you don't want to pass entities around. It can break in a lot of subtle ways as well as setting you up for unintended data disclosure.

I'll read up on that, thank you! I wasn't aware it could go wrong like that and you probably saved me hours of frustration trying to figure out how/why it was broken.

hooah
Feb 6, 2006
WTF?

Guildenstern Mother posted:

I'll read up on that, thank you! I wasn't aware it could go wrong like that and you probably saved me hours of frustration trying to figure out how/why it was broken.

It sounds like you're taking John Thompson's Spring 5 course. I'd that's so, he'll have you using DTOs at some point, although he calls them command objects.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
I'm doing launchcode actually. This is the last part with the big group project, and while we covered spring and relational db's in spring it was a much simpler overview than what I'm trying to do right now. In the spirit of the group project the guy who is supposed to be helping me with the backend has completely hosed off, and our TA is a JS guy who barely knows spring, but we haven't hosed up a merge yet so that's a good start at least.

edit: Reading up on this it seems like DTOs are there to reduce calls between the client and the server, which I'm not worried about in this case as the only external API is going to be pulling JSON from a webpage, or in the case of this particular block of code, processing a single form's data. Still good to know about, and might be helpful.

Still can't figure out that error message though, spent half the night just camping and watching the discord I posted the same question in and still nothing. I'm convinced its just me setting up one of my entities wrong. I saw that the error can occur if you do something extra silly like set up a repository as something like UserRepository extends CrudRepository <UserRepository, Integer> but I double checked and I haven't done that.

Guildenstern Mother fucked around with this message at 16:35 on Jan 9, 2022

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

Guildenstern Mother posted:

So I'm trying to write a spring controller that will add a recipe to my sql db. Ingredients are unique and don't contain a recipeId and its all tied together in a junction table that looks kinda like this:
code:
junction table

idJunction	idRecipe	idIngredient	idUnits	amount
1		1		1		3		1
2		1		2		2		16
3		2		3		2		8
4		1		3		2		4

Assuming I've got all my entities set up correctly how much of the work can I expect spring to do wrt to populating the junction table? Will I need to save to the junctionRepository?

edit: Of course I will, because the junction entry has the prep notes and quantities for the ingredients.

If each ingredient is coming back from the form with notes about measurement, quantity and prep notes could I make those transient properties in ingredients so that while they're there to be entered into the junction table they're not stored as part of the main ingredient entry or is that going to screw everything up?

edit edit: Doing that is giving me this error Inferred type 'S' for type parameter 'S' is not within its bound; should extend 'com.recipeproject.recipeproject.models.Junction'

My add junction row looks like this if its any help:

List<Ingredient> tempList = new ArrayList<>();
for (Ingredient ingredient: tempList) {Ingredient ingredient1 = new Ingredient();
junctionRepository.save(newRecipe, ingredient, ingredient.getMeasurement(), ingredient.getAmount(), ingredient.getPrepNotes() );

First, what you're calling a junction table isn't really, as a junction table just contains the ids of the two tables you're joining in a many to many relationship. Instead you have an entity with it's own properties that has many to one relationship with both Recipes and Ingredients and could be referred to a RecipeLineItem or something similar.

It does require it's own repository since it's not a junction table (which JPA could handle completely for you if it were via annotations, no repo needed) and the repo should have save methods that just take an instance of that entity as an argument, not individual properties as parameters. These properties all belong on the RecipeLineItem entity, where they will be saved, not as transient properties elsewhere.

In the code you linked you're trying to pass all those properties to your repo save method instead of passing an instance of the class to be saved.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?

RandomBlue posted:

First, what you're calling a junction table isn't really, as a junction table just contains the ids of the two tables you're joining in a many to many relationship. Instead you have an entity with it's own properties that has many to one relationship with both Recipes and Ingredients and could be referred to a RecipeLineItem or something similar.

It does require it's own repository since it's not a junction table (which JPA could handle completely for you if it were via annotations, no repo needed) and the repo should have save methods that just take an instance of that entity as an argument, not individual properties as parameters. These properties all belong on the RecipeLineItem entity, where they will be saved, not as transient properties elsewhere.

In the code you linked you're trying to pass all those properties to your repo save method instead of passing an instance of the class to be saved.

Gotcha, that makes sense. I'll try that when I get home and hopefully that fixes it.

smackfu
Jun 7, 2004

At least fighting with Spring and JPA is a real job skill.

RandomBlue
Dec 30, 2012

hay guys!


Biscuit Hider

smackfu posted:

At least fighting with Spring and JPA is a real job skill.

Now try to make Spring Boot start up in an acceptable amount of time.

hooah
Feb 6, 2006
WTF?
It starts up a hell of a lot faster than JBoss, at least at my job.

FateFree
Nov 14, 2003

Hey I'm building a spring boot rest api and we've just been looking at the log file from logback manually. Is there some nice open source UI that can ingest the log file and make it nicer to search/group by levels, whatever else fun logging features? Ideally just a dependency that creates a ui endpoint (kinda like how swagger ui does for the apis)

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
you may also want to try cleaning your dependencies down to a more minimal set - I think there is a certain amount of scanning and autowiring that spring has to do for each class/package and if you're pulling in a lot, then it has to do more work. Make sure you have a packageScan defined as well.

it's hard to say how much could be down to cleaner dependencies vs just pulling out a few bad offenders that we didn't really need (one was starting an embedded tomcat I think) but after I stripped down our dependencies our startup time probably got cut in 1/2 or 1/3, it went from pokey as hell to just a couple seconds, which, whatever. We actually went up to DEBUG level logging not long after that, and despite using synchronous logging appenders (and despite DEBUG logging being kind of a worst case scenario for startup with Spring splattering 50 billion configuration messages) we actually still started probably twice as fast even with the increased logging.

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE

FateFree posted:

Hey I'm building a spring boot rest api and we've just been looking at the log file from logback manually. Is there some nice open source UI that can ingest the log file and make it nicer to search/group by levels, whatever else fun logging features? Ideally just a dependency that creates a ui endpoint (kinda like how swagger ui does for the apis)

you're looking for filebeat or logstash

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

FateFree posted:

Hey I'm building a spring boot rest api and we've just been looking at the log file from logback manually. Is there some nice open source UI that can ingest the log file and make it nicer to search/group by levels, whatever else fun logging features? Ideally just a dependency that creates a ui endpoint (kinda like how swagger ui does for the apis)

Grafana with Loki. It’s a dream. We left Logstash and have never looked back.

Votlook
Aug 20, 2005

Hippie Hedgehog posted:

Grafana with Loki. It’s a dream. We left Logstash and have never looked back.

Elasticsearch and Kibana are good and fine software, but Logstash is complete trash, it is the black sheep of the ELK family.

abraham linksys
Sep 6, 2010

:darksouls:
grafana cloud is free to start and i think pretty price competitive. i will say the ui for actually getting to the logs with loki is kind of weird compared to other dedicated logging systems (you basically have to "define a query" every time), but once you figure that out it's pretty nice (and ui improvements for this are at least on their roadmap). integrates well with metrics/traces if you decide to do that through grafana too

depending on how simple your logging is you might be best off with just papertrail though, we use it at work to handle a ton of logs that are too inconsistent to do anything structured with and we're pretty happy with it (tried to move to new relic logs at one point to get the integrations with their APM stuff and holy poo poo that was an awful nightmare of a product)

e: after writing this i reread your post and realized you were specifically asking for open source options, whoops. still, if you're okay with something paid and hosted, i think these are decent options

abraham linksys fucked around with this message at 22:07 on Jan 11, 2022

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?
I wouldn't run grafana + loki paid when it's so easy to set them up on a local cloud. Well, maybe if you don't have one of those... Of course, just a few containers will do.

But one of the biggest selling points IMO is how well Prometheus and Loki integrate with Kubernetes and containers on K8s as data soures, if that's the platform you're on.

F_Shit_Fitzgerald
Feb 2, 2017



Is there a way to give a unique numerical ID to each object of a class that I create?

For example, if I said

Object myObj1 = new Object();
Object myObj2 = new Object();

...and then invoked

myObj1.getID();
myObj2.getID();

...I'd get, say, '0' and '1' respectively.

(No, this is not for homework but for a small project I'm doing for fun/learning.)

hooah
Feb 6, 2006
WTF?
You'd probably want to make your constructor private (I guess with a static initializer or @PostConstruct if this is in a container) and use a builder pattern.

CPColin
Sep 9, 2003

Big ol' smile.
You probably wouldn't want to do this in a "real" project, because it would be tough to test, but you could have a static field in the class that's an AtomicInteger you increment in the constructor. I bet this would count as a code smell nowadays.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
An easy way to do this is to use a static class field:

code:
public class MyClass {
	private static int nextId = 0;

	private int id;

	public MyClass() {
		this.id = nextId++;
	}
}

F_Shit_Fitzgerald
Feb 2, 2017



Thanks! This project couldn't come at a better time because I'm realizing how rusty I am at Java...

hooah
Feb 6, 2006
WTF?

Jabor posted:

An easy way to do this is to use a static class field:

code:
public class MyClass {
	private static int nextId = 0;

	private int id;

	public MyClass() {
		this.id = nextId++;
	}
}

Wait, static primitives can be mutated?

Twerk from Home
Jan 17, 2009

This avatar brought to you by the 'save our dead gay forums' foundation.

Jabor posted:

An easy way to do this is to use a static class field:

code:
public class MyClass {
	private static int nextId = 0;

	private int id;

	public MyClass() {
		this.id = nextId++;
	}
}

Is incrementing always atomic, or would this also require the constructor to be synchronized?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Twerk from Home posted:

Is incrementing always atomic, or would this also require the constructor to be synchronized?

Incrementing is not atomic, if you wanted to construct these objects across multiple threads then you would need some synchronization.

The best way to do that would be to use an AtomicInteger instead of an int to hold the next id.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

hooah posted:

Wait, static primitives can be mutated?

Fields (including static fields) can be reassigned with new values as long as they're not final.

hooah
Feb 6, 2006
WTF?

Jabor posted:

Fields (including static fields) can be reassigned with new values as long as they're not final.

Ah, of course. I scanned the declaration and assumed it included final.

zombienietzsche
Dec 9, 2003
What're some good books for a .NET guy get up to speed on Java? It looks like Modern Java in Action followed by Optimizing Java is the way to go, but I think MJIA might be pretty outdated?

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
I'm working on a project with a buddy and when I go to run his latest push I'm getting this error.
code:
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class
Application properties in question:

code:
spring.mvc.view.prefix=/WEB-INF/
spring.datasource.url=jdbc:mysql://localhost:3306/moto
spring.datasource.username=****
spring.datasource.password=****
spring.jpa.hibernate.ddl-auto=update
spring.mvc.hiddenmethod.filter.enabled=true
spring.jackson.serialization.write-dates-as-timestamps: false
adding these lines didn't fix it, but I'm pretty sure the problem is something related to the bolded one that needs fixing
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true


I'm assuming something in application properties is the culprit, but stackoverflow also told me that adding this line: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) would fix it but didn't make any mention of where to put it. Application properties? I've never seen anything starting with an @ in there, but I'm an idiot so maybe that's normal.
edit: It goes in the main application class duh. Fixed the first problem but now its giving me all sorts of bean errors in my service classes so I'm not sure that was the solution I needed.

Guildenstern Mother fucked around with this message at 23:56 on Feb 17, 2022

Splinter
Jul 4, 2003
Cowabunga!

Guildenstern Mother posted:

I'm assuming something in application properties is the culprit, but stackoverflow also told me that adding this line: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) would fix it but didn't make any mention of where to put it. Application properties? I've never seen anything starting with an @ in there, but I'm an idiot so maybe that's normal.

That's a class annotation, not something you'd put in application.properties. That would go on your main application class. The one that contains public static void main, and calls SpringApplication.run(). I would think you'd already have that class annotated with @SpringBootApplication (with no additional parameters), they are just suggesting adding that exclude parameter to the annotation. However, I wouldn't rule out you having some other issue with your config, as I would expect you'd be able to connect to a MySQL DB without needing that exclude. It could be an issue with dependencies or project structure. Are you sure the DB server is up and running? A maven clean install couldn't hurt.

You might want to try com.mysql.cj.jdbc.Driver instead of com.mysql.jdbc.Driver. However, again, with proper dependencies and project config I'm not sure you should even have to set the driver-class-name in the properties file. On my current project with mysql I'm not setting that anywhere. Are you using spring-boot-starter-data-jpa and spring-boot-starter-web and mysql-connector-java?

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
Honestly I'm coming in at the tail end of this project of his so I'm not 100% familiar with all the code yet. Sadly the com.mysql.cj.jdbc.Driver suggestion didn't work. I did check the dependencies and he is using both spring-boot-starter-data-jpa and spring-boot-starter-web and mysql-connector-java, everything there looked like it should, and it was running the last time I fired it up (about 3 pushes ago). Checking the github logs the only change to non jsp/css files has been adding in which I wouldn't think would cause the problems here, its gotta be something in the application properties.
code:
<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-joda</artifactId>
			
		</dependency>

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Guildenstern Mother posted:

I'm working on a project with a buddy and when I go to run his latest push I'm getting this error.
code:
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class
Application properties in question:

code:
spring.mvc.view.prefix=/WEB-INF/
spring.datasource.url=jdbc:mysql://localhost:3306/moto
spring.datasource.username=****
spring.datasource.password=****
spring.jpa.hibernate.ddl-auto=update
spring.mvc.hiddenmethod.filter.enabled=true
spring.jackson.serialization.write-dates-as-timestamps: false
adding these lines didn't fix it, but I'm pretty sure the problem is something related to the bolded one that needs fixing
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true


I'm assuming something in application properties is the culprit, but stackoverflow also told me that adding this line: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) would fix it but didn't make any mention of where to put it. Application properties? I've never seen anything starting with an @ in there, but I'm an idiot so maybe that's normal.
edit: It goes in the main application class duh. Fixed the first problem but now its giving me all sorts of bean errors in my service classes so I'm not sure that was the solution I needed.

I would expect that to happen since you are telling Spring to not start the DataSourceAutoConfiguration which would create the Bean needed by all of your data classes, so of course they are complaining about a missing bean. That kind of fix is like my monitor looks fuzzy, solution: unplug it.

It could be a few issues, the properties you are setting are not the ones that Spring is looking for. i.e it can't find the URL because it's looking for it under a different prefix i.e. when using a connection pool. But I doubt this is your case since you are just trying to get it to talk to a single mysql db instance.
I am going to guess and say that your mysql driver is not somewhere on the classpath that Spring can find. It does something on startup that registers the driver as something that can handle the jdbc:mysql url. If it's not on the classpath then the URL isn't going to work and leads to the kind of errors you are seeing. I recall having to manually put the jdbc driver in a tomcat folder, but I thought new Spring Boot stuff got rid of that. Still worth a shot to make sure the mysql driver is getting loaded in the embedded application server.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
Turned out to be a weird intellij problem, I had to change a setting on the webapp folder

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
One other thing I’ll throw out, my last workplace had a “HibernateConfig.java” that ripped and renamed certain properties and programmatically initialized the datasource. As bad as that sounds it wouldn’t surprise me at all if that’s what the spring boot tutorials or some online “how to hibernate in spring” tutorial told them to do.

I see you got it, but that’s a thing to check too, sometimes people migrate forward from older versions that did things a little differently or follow lovely tutorials and you should make sure the value are actually getting set on the objects themselves.

It produces a lot of logspam until you tune it but turning logging to DEBUG level will provide a wealth of information about how Spring is wiring its configuration and you can tune a lot of the really useless stuff and leave it with the things it’s auto wiring, their configs, the package paths it’s searching, etc. When spring or hibernate or Jackson etc etc are doing weird poo poo turning the logging up and looking at the reasons it’s doing those things is invaluable and highly efficient, it’s way better than reading tutorials or trying to second guess config files/etc. Is it getting picked up? Either way that gives you a direction to focus on.

Guildenstern Mother
Mar 31, 2010

Why walk when you can ride?
I got pretty good with the debugger for checking that object data was set correctly in my last project and it's such a helpful tool. It's one of those things I wish they'd actually teach in boot camp instead of the 5 min "this is the debug button and you can set breakpoints, moving on" I got. Maybe it's something you really only learn when you're forced to by circumstance, like the first time someone tries to explain a git merge to you and literally nothing is retained except a few vague terminal commands and the word conflict.

Btw to the guy who told me to go back and fix my classes to match the JSON data I was going to be taking in and I ignored the last time I was in here asking questions: holy poo poo you were so right. I'm redoing the project from scratch because the group project part of it went horribly and I don't want it in my portfolio and step one was doing a much better job designing my classes so 40% of them aren't basically redundant. It would have saved so much work to have done that at the start.

Guildenstern Mother fucked around with this message at 11:03 on Feb 18, 2022

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
I'm thinking of a project that reduces nicely to a state machine. I did PROLOG in college and the "pattern-matching guard" syntax is very intuitive for that type of thing - where you say like:

code:
//essentially a list of edges in the state machine:
execute(state1, myVerb, theThing) :- do_the_thing();
execute(state1, myVerb, otherThing) :- do_other_thing();
execute(_, _, _) :- throw_unknown_token_exception();
Is there a way to have that kind of syntax, but compile it to Java and embed it in some other application? Like maybe via Groovy or something?

Or, is there another good way to do state machines on Java?

Paul MaudDib fucked around with this message at 09:35 on Feb 26, 2022

zombienietzsche
Dec 9, 2003
When I think of distributed state machines on the JVM, I think of Akka, but I'm not terribly familiar with the ecosystem and the "distributed" part might be overkill.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
I recall using an Enum to express the states of the SM and then creating a SM interface that defined the actions and the Enum implement it. In each enum I then had to define the action and return the next state. Then I created a execution class that would take that SM interface and basically just go through a loop until it reaches a terminal state. I don't know if it could be made simpler with the newer Java versions, but that should give you an idea.

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE

Janitor Prime posted:

I recall using an Enum to express the states of the SM and then creating a SM interface that defined the actions and the Enum implement it. In each enum I then had to define the action and return the next state. Then I created a execution class that would take that SM interface and basically just go through a loop until it reaches a terminal state. I don't know if it could be made simpler with the newer Java versions, but that should give you an idea.

I bet you can make the C++ template generator into a state machine :buddy:

(yes, it appears you can :buddy:)

Adbot
ADBOT LOVES YOU

Hippie Hedgehog
Feb 19, 2007

Ever cuddled a hedgehog?

Paul MaudDib posted:

Or, is there another good way to do state machines on Java?

Use a library.

Here's the first google result, I haven't used it myself:
https://github.com/stateless4j/stateless4j

This one looks elegant, but is for Kotlin:
https://github.com/Tinder/StateMachine

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