In my Java code, I have a field named isNegative with a similar column existing in database. But Hibernate insists the name should be is_negative, even with forcing the name with #Column.
#Column(name="isNegative")
private boolean isNegative;
Error:
Caused by: org.hibernate.HibernateException: Missing column:
is_negative in datasource.item
Application.properties:
#JPA
spring.data.jpa.repositories.enabled=false
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.open-in-view=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.properties.hibernate.event.merge.entity_copy_observer=allow
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
That's due to your configuration, because you are setting spring.jpa.hibernate.naming.physical-strategy to PhysicalNamingStrategyStandardImpl which will use underscores for the names.
If you check the Configure Hibernate Naming Strategy section of Spring Docs, you can see that:
Hibernate uses two different naming strategies to map names from the object model to the corresponding database names. The fully qualified class name of the physical and the implicit strategy implementations can be configured by setting the spring.jpa.hibernate.naming.physical-strategy and spring.jpa.hibernate.naming.implicit-strategy properties, respectively. Alternatively, if ImplicitNamingStrategy or PhysicalNamingStrategy beans are available in the application context, Hibernate will be automatically configured to use them.
By default, Spring Boot configures the physical naming strategy with
SpringPhysicalNamingStrategy. This implementation provides the same
table structure as Hibernate 4: all dots are replaced by underscores
and camel casing is replaced by underscores as well. By default, all
table names are generated in lower case, but it is possible to
override that flag if your schema requires it.
To solve that you need to remove this property and use the default naming strategy instead:
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
You would need spring.jpa.hibernate.naming.physical-strategy and spring.jpa.hibernate.naming.implicit-strategy
Adding following
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
to application.properties could help. This solution would work from hibernate 5.
Hope it helps.
Please find below my analysis:
If you don't want your naming strategy to add an underscore to the column name or class name, then the strategy that you need to use would look like: spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl. The things that you provide in annotations #Table and #Column’s name attribute would remain as it is. E.g. firstName attribute in entity will get a column name as firstName i.e. No change.
If you don't want to provide annotations and want to manually handle the table name and column names, you should extend the class org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl and override the required methods. If you still use annotations for some of the cases here, remember the overridden methods will apply on the names written in those annotations. spring.jpa.hibernate.naming.physical-strategy=example.CustomStrategy
Related
This is driving me mad.
I'm implementing Spring Social and it requires you to have a database table named UserConnection (instead of using the standard naming convention of using an underscore to separate the two words).
So in my naive world view, I assumed it would be easily solved by specifying #Table(name="UserConnection")... but no, that would be all too easy.
The annotation is ignored and the table is created as user_connection which then causes Spring Social to have a hissy fit.
Please tell me there's some easy way to tell my Spring Boot app to just name that one table (and its corresponding columns) to use a camel-case naming convention instead of the standard one.
TL; DR
Add the following to your application.yml file:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Or your application.properties:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Detailed Answer
As Spring Boot 1.4 release notes states:
SpringNamingStrategy is no longer used as Hibernate 5.1 has removed
support for the old NamingStrategy interface. A new
SpringPhysicalNamingStrategy is now auto-configured which is used in
combination with Hibernate’s default ImplicitNamingStrategy. This
should be very close to (if not identical) to Spring Boot 1.3
defaults, however, you should check your Database schema is correct
when upgrading.
This new PhysicalNamingStrategy follows Spring recommended naming conventions. Anyway if you want total control over physical naming, you're better off using the org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl. You can switch to that naming strategy by adding the following to your application.yml:
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
The annotation is ignored and the table is created as user_connection
which then causes Spring Social to have a hissy fit.
The apply method of SpringPhysicalNamingStrategy is the key to understand this behavior:
private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
if (name == null) {
return null;
}
StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
for (int i = 1; i < builder.length() - 1; i++) {
if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i),
builder.charAt(i + 1))) {
builder.insert(i++, '_');
}
}
return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
}
private boolean isUnderscoreRequired(char before, char current, char after) {
return Character.isLowerCase(before) && Character.isUpperCase(current)
&& Character.isLowerCase(after);
}
It basically replaces any . and case changes (take a look at isUnderscoreRequired method) with an underscore.
Option 1
First of all define your tables name on the #Entity mapping:
#Entity( name = "UserConnections")
public class UserConnection{
Option 2
You should pay a bit with the NamingStrategy. When you define your properties for the sessionFactory bean then try adding this:
<prop key="hibernate.implicit_naming_strategy">legacy-jpa</prop>
When an entity does not explicitly name the database table that it
maps to, we need to implicitly determine that table name. Or when a
particular attribute does not explicitly name the database column that
it maps to, we need to implicitly determine that column name.
So if you do not want to explicitly name your table names for each of the entities you should follow this strategy.
Option 3
Alternatively if the above do not work for you, you have to use the PhysicalNamingStrategy. Though this is the last resort in your case:
REference: https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/naming.html
I have been facing this weird exception while trying to persist some values into a table using Hibernate in a Java application. However this exception occurs only for one particular table/entity for rest of the tables i am able to perform crud operations via Hibernate.
Please find below the Stacktrace and let me know if this is anyway related to java code is or its a database design error.
2016-04-28 11:52:34 ERROR XXXXXDao:44 - Failed to create sessionFactory object.org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table found in namespace (, ) : YYYYYYY
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.XX.dao.XXXXXXXDao.main(XXXXXXXXDao.java:45)
Caused by: org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table found in namespace (, ) : YYYYYYY
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults(InformationExtractorJdbcDatabaseMetaDataImpl.java:381)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTable(InformationExtractorJdbcDatabaseMetaDataImpl.java:279)
at org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl.getTableInformation(ImprovedDatabaseInformationImpl.java:109)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:252)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:64)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:458)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at com.xx.dao.zzzzzzzzzzzzDAOFactory.configureSessionFactory(zzzzzzzDAOFactory.java:43)
at com.xx.dao.zzzzzzzzzzzzDAOFactory.buildSessionFactory(zzzzzzzzzDAOFactory.java:27)
at com.xx.dao.XXXXXXXXDao.main(XXXXXXXXDao.java:41)
Thanks in advance for your help
I have had the same problem and was able to dig down to the code to find out the cause, at least in my case. I don't know whether it will be the same issue for you but this may be helpful.
From your stack trace I can see you have the hibernate.hbm2ddl.auto set to upgrade the schema. As part of this, it is trying to look up the metadata for all the tables hibernate knows about and for one of them getting an ambiguous answer because the metadata query is returning more than a single row of table or view metadata.
In my case this was caused by our naming convention for tables. We had a table called (say) "AAA_BBB" for which this was going wrong. Now the use of an underscore in the table name is perfectly acceptable as far as I am aware and is quite common practice. However the underscore is also the SQL wildcard for a single character; looking in the code for the database metadata I can see it is doing a "WHERE table_name LIKE ..." in DatabaseMetaData.getTables(...) method, which is what hibernate is using here.
Now, in my schema I also had a second table called "AAA1BBB" and hence both of these matched the metadata lookup and so it returned a metadata row for each of these tables. The hibernate method is written to just fall down if the result set from the table metadata lookup returns more than one row. I would guess it should examine the available row(s) and find if there is one which is an exact match with the specified table name.
I tested this for both Oracle and MySQL with the same result.
Seems the property hibernate.hbm2ddl.auto set to update is causing the issue here. Try removing it from your hibernate config xml.
This will work:
Check your database schema/s and your database user privileges;
Hibernate update mechanism may fail with this exception if there is a another database schema/user with the same table name, and the db user has the sufficient privileges to view this table.
So in your case, the table 'YYYYYYY' may be found in more than one database user/schema, and your db user has 'DBA' privileges.
To solve this you can either find and delete the ambiguous table or remove the user's redundant privileges.
Another situation may be occurred except whatever dear RichB has been stated.
in ORACLE every user has separate schema ,
Therefore probably there is tow tables with the same name in two different schemes
then you should specify your default schema in persistence.xml with below property
<property name="hibernate.default_schema" value="username"/>
Use catalog value with #Table, i.e.:
#Entity
#Table(**catalog = "MY_DB_USER"**, name = "LOOKUP")
public class Lookup implements Serializable {
}
I don't have this error now.
Hope this work.
We had a Spring Data / JPA application and this error started happening after upgrading to Postgres 10.6 (from 10).
Our solution was as follows, in our JPA configuration class: note the new commented line,
props.put("hibernate.hbm2ddl.auto", "none"); //POSTGRES 10 --> 10.6 migration
Class:
#Configuration
#EnableJpaRepositories(basePackages = "app.dao")
#ComponentScan(basePackages = { "app.service" })
#EnableTransactionManagement
public class JpaConfig {
#Autowired
DataSource dataSource;
#Bean
public Map<String, Object> jpaProperties() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("hibernate.dialect", PostgreSQL95Dialect.class.getName());
props.put("hibernate.hbm2ddl.auto", "none"); //POSTGRES 10 --> 10.6 migration.
return props;
}
So after having the same issue, it turns out that I needed to update my OJDBC driver from ojdbc6 to ojdbc8. Hopefully this helps.
I have same issue with such configuration
#Entity
#Table(name = "NOTIFICATION")
public class Notification {
...
}
issue was resolved for me when I moved table name from #Table to #Entity
#Entity(name = "NOTIFICATION")
#Table
public class Notification {
...
}
Simply, if u are using two schemas then u will get this error. To resolve this error u can use these steps :
1. You need to delete extra schema.
2. Or u can define default schemas or that schema are u using.
spring.jpa.properties.hibernate.default_schema=nameOfSchema
and
jdbc:postgresql://localhost:5432/databaseName?currentSchema=nameOfSchema
I also came across this issue. Here is my solution:
the error:
https://gist.github.com/wencheng1994
I solve that. It mainly because the db account has a higher authority. I set the "hibernate.hbm2ddl.auto=update", So when hbm2ddl works, it tried to find all exists shcema I defied. But there is two schema exist the table with the same name. then the db account can find that. so it found "more than one table in the namespace"
All I need to do is to make the db account lower authority so that it can not find table in other schema. (one shcema relation one db account).
I'm using the Java Persistence API to describe tables from my database that i will manipulate in my code.
However, the schema used is not be the same depending on where my project will be installed. So, when I use the annotations, I would like that the SCHEMA field was a variable, but I can't make it:
#Entity
#Table(name = "TABLE_NAME", schema = schemaVariable, catalog = "")
How can I achieve that?
Is it possible with the persistence.xml file?
No, this is not possible. You can only use compile-time constants (which are all primitives and String) in annotations.
You can use final variables:
public class DatabaseMetadata {
public static final SCHEMA = "MySchema";
}
and then use it in annotation:
#Table(name = "TABLE_NAME", schema = DatabaseMetadata.SCHEMA, catalog = "")
but I think it's not what you wanted.
PS. On the other hand, there can be find examples of using i.e. Spring EL in annotations (see #Value annotation), but this requires custom annotation processor. AFAIK none of JPA providers gives you such ablility.
Putting schema information (like table, column, schema names) in java classes is a bad idea any time IMHO (forcing recompile if you want to deploy elsewhere). You could put that info in orm.xml and just deploy a different orm.xml dependent on your deployment requirement.
As for persistence.xml you would be dependent on your JPA provider having a persistence property that defined the default schema/catalog. I know DataNucleus JPA (what I use) has this, but no idea for Hibernate
If you know that you would be using different schemas, I'd suggest to use 2 mapping files and define
<entity-mappings>
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>HR</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
...
</entity-mappings>
In this way you will be able to easily change schemas, without any changes in the application code.
I have a Spring Boot application with dependency spring-boot-starter-data-jpa. My entity class has a column annotation with a column name. For example:
#Column(name="TestName")
private String testName;
SQL generated by this created test_name as the columns name. After looking for a solution I have found that spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy solved the problem (column name is taken from column annotation).
Still, my question is why without naming_strategy set to EJB3NamingStrategy JPA is ignoring column annotation? Maybe hibernate dialect has something to do with it? I'm connecting to MS SQL 2014 Express and my logs contain:
Unknown Microsoft SQL Server major version [12] using SQL Server 2000 dialect
Using dialect: org.hibernate.dialect.SQLServerDialect
For Hibernate 5, I solved this issue by adding the following lines in my application.properties file:
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
By default Spring uses org.springframework.boot.orm.jpa.SpringNamingStrategy to generate table names. This is a very thin extension of org.hibernate.cfg.ImprovedNamingStrategy. The tableName method in that class is passed a source String value but it is unaware if it comes from a #Column.name attribute or if it has been implicitly generated from the field name.
The ImprovedNamingStrategy will convert CamelCase to SNAKE_CASE where as the EJB3NamingStrategy just uses the table name unchanged.
If you don't want to change the naming strategy you could always just specify your column name in lowercase:
#Column(name="testname")
It seems that
#Column(name="..")
is completely ignored unless there is
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
specified, so to me this is a bug.
I spent a few hours trying to figure out why #Column(name="..") was ignored.
The default strategy for #Column(name="TestName") will be test_name, this is correct behavior!
If you have a column named TestName in your database you should change Column annotation to #Column(name="testname").
This works because database does not care if you name your column TestName or testname (column names are case insensitive!!).
But beware, the same does not apply for database name and table names, that are case sensitive on Unix systems but case in sensitive on Windows systems (the fact that probably kept a lot of people awake at night, working on windows but deploying on linux :))
The only solution that worked for me was the one posted by teteArg above. I'm on Spring Boot 1.4.2 w/Hibernate 5. Namely
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
For additional insight I'm posting the call trace so that its clear what calls Spring is making into Hibernate to setup the naming strategy.
at org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl.toPhysicalColumnName(PhysicalNamingStrategyStandardImpl.java:46)
at org.hibernate.cfg.Ejb3Column.redefineColumnName(Ejb3Column.java:309)
at org.hibernate.cfg.Ejb3Column.initMappingColumn(Ejb3Column.java:234)
at org.hibernate.cfg.Ejb3Column.bind(Ejb3Column.java:206)
at org.hibernate.cfg.Ejb3DiscriminatorColumn.buildDiscriminatorColumn(Ejb3DiscriminatorColumn.java:82)
at org.hibernate.cfg.AnnotationBinder.processSingleTableDiscriminatorProperties(AnnotationBinder.java:797)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:561)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:245)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
- locked <0x1687> (a java.util.concurrent.ConcurrentHashMap)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
- locked <0x1688> (a java.lang.Object)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
Turns out that I just have to convert #column name testName to all small letters, since it was initially in camel case.
Although I was not able to use the official answer, the question was able to help me solve my problem by letting me know what to investigate.
Change:
#Column(name="testName")
private String testName;
To:
#Column(name="testname")
private String testName;
teteArg, thank you so much.
Just an added information so, everyone bumping into this question will be able to understand why.
What teteArg said is indicated on the Spring Boot Common Properties: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
Apparently, spring.jpa.hibernate.naming.strategy is not a supported property for Spring JPA implementation using Hibernate 5.
you have to follow some naming strategy when you work with spring jpa. The column name should be in lowercase or uppercase.
#Column(name="TESTNAME")
private String testName;
or
#Column(name="testname")
private String testName;
keep in mind that, if you have your column name "test_name" format in the database then you have to follow the following way
#Column(name="TestName")
private String testName;
or
#Column(name="TEST_NAME")
private String testName;
or
#Column(name="test_name")
private String testName;
I also tried all the above and nothing works. I got field called "gunName" in DB and i couldn't handle this, till i used example below:
#Column(name="\"gunName\"")
public String gunName;
with properties:
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
also see this:
https://stackoverflow.com/a/35708531
If you want to use #Column(...), then use small-case letters always even though your actual DB column is in camel-case.
Example: If your actual DB column name is TestName then use:
#Column(name="testname") //all small-case
If you don't like that, then simply change the actual DB column name into:
test_name
I tried all the above and it didn't work. This worked for me:
#Column(name="TestName")
public String getTestName(){//.........
Annotate the getter instead of the variable
In my case, the annotation was on the getter() method instead of the field itself (ported from a legacy application).
Spring ignores the annotation in this case as well but doesn't complain. The solution was to move it to the field instead of the getter.
Using maven 3.8.3, I found funny case where the column name of the table is following the get/set method naming. Even when I added a new field in the entity, it didn't create a new column in the table if I didn't specify the get/set method.
But, if I remove all get/set methods from the entity class, the naming of columns in the table follows the naming of fields in the entity class.
(I'm a rookie, it might be a feature which ensures logical correctness :)
E.g. I have:
#Column(name = "username")
private String m_username;
Note that the #Column annotation only affects the database column name.
Hibernate still thinks the name of the property is 'm_username'.
How can I tell Hibernate that the property name is just 'username'?
Please tell me there is a way to do this...
Edit: I removed the #AccessType annotation in my code example, as it is not relevant for this question.
Update: After switching everything to field access, this exception happens:
org.hibernate.QueryException: could not resolve property: username of: mypackage.model.User
It happens here:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("username", username));
User result = (User) criteria.uniqueResult();
And the reason is most likely that hibernate only 'knows' of a property called 'm_username', while I think of it and program against a property named 'username'. Also note that my getters/setters are called: "getUsername()" and "setUsername(String value)" (automatically generated).
why do you use AccessType.PROPERTY?
remove it and it is accessed by 'field'.
do not mix field and property annotations. stick to one or the other.
As per my knowledge we can't* .
There is still one issue with the way hibernate looks up the methods
for a given property name.
Suppose you have a property with a name like "mProperty" (first
lowercase, second uppercase, rest doesn't matter). Not the accessor
methods in the source code will be getMProperty and setMProperty.
The way BasicPropertyAccessor.getterMethod is implemented in that way .
I found one lead here: https://forum.hibernate.org/viewtopic.php?f=1&t=943110
But the thread is 7 years old and I don't know how to apply this to annotation based configuration (I don't have an xml configuration file).