Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HHH-18693 Hibernate Processor does not handle inner types #9098

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

cigaly
Copy link
Contributor

@cigaly cigaly commented Oct 16, 2024

See Jira Issue HHH-18693

This is still work in progress, not to be merged with main branch, at least not immediately.

For each (static) inner non-private class one meta-model class will be generated.

Naming is as follows. If we have:

class A {
    ...
    @Entity
    static class B {
        ...
    }
    ...
}

Generated class will be named A_B_


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


@cigaly
Copy link
Contributor Author

cigaly commented Oct 16, 2024

Some existing test classes were changed to make inner classes non-private. Otherwise such class could not be referenced from meta model class.

@gavinking
Copy link
Member

Thanks for working on this @cigaly !

@cigaly cigaly force-pushed the HHH-18693-Hibernate_processor-Inner_classes branch from 965c5f0 to c20fa62 Compare October 23, 2024 14:14
@gavinking
Copy link
Member

Some existing test classes were changed to make inner classes non-private. Otherwise such class could not be referenced from meta model class.

I think the Processor is still going to have to be able to elegantly handle private inner classes; we don't want to simply disallow that.

So I'm not quit sure what "elegantly" means here ... perhaps it just means "skip them".

@cigaly cigaly force-pushed the HHH-18693-Hibernate_processor-Inner_classes branch from c20fa62 to a8fb6dd Compare October 24, 2024 06:28
@cigaly
Copy link
Contributor Author

cigaly commented Oct 24, 2024

So I'm not quit sure what "elegantly" means here ... perhaps it just means "skip them".

Other than disallowing private classes (either inner or top-level) , excluding them from metamodel generation is only solution that will not cause Java compilation errors. And, of course, there is always possibility that private static class could be referenced by either top level class containing private class or other inner class contained by same top level class.

Now only one test class has to be changed to avoid compilation errors is org.hibernate.orm.test.schematools.PrimaryKeyColumnOrderTest.EntityId. Here metemodel generated from

	public static class EntityId implements Serializable {
		private int A;
		private int B;
	}

will result in

public abstract class PrimaryKeyColumnOrderTest_EntityId_ {
	public static final String A = "A";
	public static final String B = "B";
	public static volatile SingularAttribute<EntityId, Integer> A;
	public static volatile SingularAttribute<EntityId, Integer> B;
	public static volatile EmbeddableType<EntityId> class_;
}

which is definitely something Java is happy with. Perhaps some mechanism can be added to prevent such duplications, but until then this class should be slightly changed to let tests to run.

@gavinking
Copy link
Member

gavinking commented Oct 24, 2024

Now only one test class has to be changed to avoid compilation errors is

Hurm.... so that's actually a hole in the algorithm defined by the spec, isn't it? We should fix that, in both Processor, and in the spec. For example, we could say that A -> _A.

@cigaly
Copy link
Contributor Author

cigaly commented Oct 24, 2024

This is more like one of those "tricky" questions for entertainment pages of some Java magazine. Something like "how are named getters and setters in a class with int property named abc and String property named Abc".

It seems that in current code only problematic are properties with name consisting of single uppercase letter. To fix that (at least, until some other solution) I will change method org.hibernate.processor.util.StringUtil#getUpperUnderscoreCaseFromLowerCamelCase by inserting right after method declaration lines

		if (lowerCamelCaseString.length()== 1 && lowerCamelCaseString.toUpperCase().equals( lowerCamelCaseString )) {
			return "_" + lowerCamelCaseString;
		}

(or, maybe, to use underscore as a suffix?)

If nothing else, this will allow implement metamodel class generation for inner classes, without touching any core (main or test) code.

@cigaly cigaly force-pushed the HHH-18693-Hibernate_processor-Inner_classes branch from a8fb6dd to 83e4d1e Compare October 24, 2024 07:40
@gavinking
Copy link
Member

Yeah but you can just use Character.isUpperCase() 😜

@cigaly
Copy link
Contributor Author

cigaly commented Oct 24, 2024

Yes, you are right. It seems that I am still sleepy :-)

….hibernate.processor.util.StringUtil#getUpperUnderscoreCaseFromLowerCamelCase
@cigaly cigaly force-pushed the HHH-18693-Hibernate_processor-Inner_classes branch from 83e4d1e to 3d9520b Compare October 24, 2024 07:45
@cigaly cigaly marked this pull request as ready for review October 25, 2024 09:31
…odelClassName(java.lang.String) to handle metamodel classes generated from inner class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants