Duplicate Tasks & proxy
Indeed, Exception has a lazy reference to its Excepted. But if I remove the lazyness from that relation I get a stack overflow, presumably because the Excepted (in this specific case: Task) also has an eager relation to its Exceptions. If I remove the eagerness there, it mostly works as expected, but I do see why I set the lazyness of Exception.excepted in the first place: after I issue
FROM School AS s LEFT JOIN FETCH s.tasks AS t LEFT JOIN FETCH t.exceptions
Hibernate still performs a new query for each of the School’s two Tasks. I don’t understand why, but it’s probably not important for my use. Something similar happens with one of the two SubTasks (which has an Exception), but not the other (which has none).
So I switched the eagernesses of these Any ⟷ OneToMany relations from their defaults and didn’t get what I expected. Is that because one is not mappedBy the other? Was it a bug, where Hibernate should detect that the HibernateProxy is actually the same as one of the Tasks and remove it? Or did I unwittingly expect something unreasonable from Hibernate?
Model
You’re right, I should have given some context. I’m working on a school information system written in PHP. There’s an old version we like to phase out, and a complete rewrite were we use Laravel. We need to register a lot of the information we process with the government, like registering new pupils, reporting their absence, diplomas obtained, et cetera. The relevant government agency exposes a SOAP interface for that, described by WSDL files. It would be nice if we could call these APIs from PHP, but my colleagues and I have not found a convenient way to do this. So the way we do this in the old version is that every piece of information to be sent to the government is recorded in a database, and from time to time we use a small Java program to read this new information from this database, put it in the appropriate XML format and send it to the SOAP server. We then record the results we get there in the database. The rewritten PHP code requires a rewritten Java program, and that’s what I’m working on. I picked Hibernate instead of the manually written queries we use now, which are error-prone, inflexible and don’t allow for much abstraction. It’s still a challenge, in part because I need to design a new database structure which can be worked with from both Laravel’s ORM and Hibernate, and also for my lack of experience with ORMs.
So the name Task is just a nod to our educational setting. Each Task corresponds with one SOAP call, and a SubTask is one item with an associated status and a data payload (e.g. the registration info of one pupil). The SOAP calls mostly follow a CRUD pattern, so there’s many types of SubTask. Currently we implement 41 but I expect that to increase over time, perhaps significantly so. As the Java program has limited functionality, it doesn’t need to be able to create new Tasks or SubTasks but it must be able to modify them. Perhaps some of these fiddly associations of mine are not even necessary (in which case I apologize for the noise). That’s also the reason there’s no Task.setSubTasks method.
Inheritance modelling
At the moment I have SubTask as an abstract MappedSuperclass. Table-per-class then allows to use SubTask (perhaps even Excepted?) as a query-able Entity, but there’s no differences/downsides compared to MappedSuperclass if I’m not mistaken. That would make the code a lot cleaner, at the cost of a huge UNION, right?
I’ll take a good look at your suggestions (again) and see if I can use something. “As good as it gets” seems to be the theme here, but perhaps I’ll get to something a little prettier than I have now.