Hibernate "Invalid column name" error when using a NamedNativeQuery - java

I have recently changed an object to have a #OneToMany mapping to another object, with the FetchType.LAZY. But when I try to load a list of these objects using a #NamedNativeQuery, which calls an Oracle function, it throws a java.sql.SQLException: Invalid column name for this new OneToMany mapping. But being marked as LAZY, it shouldn't try to populate this variable should it?
In theory I could change the function to return an empty value for this column (basically a hack), but I would have to roll that out to everywhere that uses a #NamedNativeQuery to populate one of these objects.
This seems like a bug to me. Is there a workaround, something I'm missing or possibly fixed in a later version of Hibernate?
I'm using hibernate-core 3.3.2.GA, hibernate-entitymanager 3.4.0.GA, hibernate-annotations 3.4.0.GA and hibernate-commons-annotations 3.3.0.ga.

Related

How to use Hibernate 5.2.10 MySQL JSON support without AttributeConverter or customUserType to map to Java Entity Class?

I am trying to map the MySQL JSON column to Java Entity class. Looking for the cleanest way of doing this.
Upon doing some research found 3 possible ways:
Extending AbstractSingleColumnStandardBasicType
Create a custom UserType
Use an attribute Converter
I used an attribute converter to convert the JSON column from String (as MySQL driver makes it to a String) to my required type - this works with both the Hibernate V4.3.10 and V5.2.10
I tried to find if JSON is natively supported in Hibernate and found the PR https://github.com/hibernate/hibernate-orm/pull/1395, based on the PR looks like it does add JSON mapping to the MySQL Dialect hence letting Hibernate know about the JSON Column.
Does this mean I can use something like this to map to JSON Column in DB ?#Column(name="json_type_column")
Private Object correspondingJsonAttribute;
If I cannot use it like this and need to use one of the above 3 methods, is there a reason I would need to upgrade to get the registerColumnType( Types.JAVA_OBJECT, "json" ); which is part of the PR and is present in Hibernate V5.2.10, Do I get any more features from V5.2.10 that support JSON columns?
I also looked into the corresponding test case to understand how the JSON column mapping is being done https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/access/MixedAccessTestTask.java, this uses #Access annotation via property, looks like it sets the corresponding JSON column variable in Entity to Map after converting it from String.
Any help is much appreciated.
Thanks!
Upon doing some research found 3 possible ways:
Extending AbstractSingleColumnStandardBasicType
Create a custom UserType
Use an attribute Converter
AttributeConvertor won't help you for this, but you can still use a custom UserType, or Hibernate Type Descriptors.
Does this mean I can use something like this to map to JSON Column in
DB?
#Column(name="json_type_column") Private Object
correspondingJsonAttribute;
No. The json type is just for JDBC so that Hibernate knows how to handle that JDBC object when setting a parameter on a PreparedStatement or when fetching a ResultSet.
Do I get any more features from V5.2.10 that support JSON columns?
No, but you just need to supply your own JSON type.
You can just use the hibernate-types which is available on Maven Central.
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And use the provided JdonType from Hibernate Types as it works on MySQL, PostgreSQL, Oracle, SQL Server or H2 without doing any modifications.

JPA / Hibernate: StringClobType deprecated

I recently upgraded Spring Boot and with this came a hibernate upgrade. Unfortunately, the entity column #Type(StringClobType) annotation has been deprecated. The documentation tell me I need to switch it to MaterilizedClobType.
Unfortunately this has broken my application.
I'm using PostgreSQL 9.5. The StringClobType annotation created a text type in the database which allowed me to store long text in the field. Unfortunately now, the string literal comes back when Hibernate is expecting some kind of LOB id.
This gives the error: Bad value for type long
The Hibernate #Type value that maps to PG's Text data type is org.hibernate.type.TextType. This is what you should use.
For what it's worth, this a sibling of org.hibernate.type.MaterializedClobType, which maps to CLOB; both are subclasses of org.hibernate.type.AbstractLongStringType.

Hibernate reveng persistence model does not validate

I use Hibernate Reverse Engineering to automatically create classes from a database scheme. DB server is MSSQL 2008. This database is designed by a partner and could potentially change without notice. Thus I'd like to have Hibernate validate the scheme on startup, wich in my opinion should work out of the box. But it doesn't:
org.hibernate.HibernateException: Wrong column type in somedb.dbo.ASVC_S for column SomeCol. Found: decimal, expected: numeric(18,0)
The generated enttity class looks like this:
#Column(name="SomeCol", precision=18)
public BigDecimal getSomeCol() {
return this.someCol;
}
Is my assumption that reveng creates classes that can be validated against the schema wrong? Should I skip validation and hope that during runtime everything's OK? Annotating the classes after generating them or maintaining an entry for each class in my reveng.xml mapping file is not an option - too many classes ;)
hibernate-tools is version 4.0.0-CR1.

Creating a new Hibernate table

So I'm still pretty new to Hibernate, and I'm working on a large-ish application that already has a database with several Hibernate tables. I'm working on a new feature, which includes a new #Entity class, and I need these objects to be stored in a new table. The class is declared like this:
#Entity
#Table(name="DATA_REQUEST")
public class DataRequest {
//Some fields, nothing fancy
}
The DATA_REQUEST table does not exist, nor do I have any data to store in it yet. I started the application up, expecting that it would either create the table or crash because it doesn't exist yet. Neither of these actually happened.
So: do I need to create the table manually (easily done)? Or do I need to go somewhere else to tell Hibernate that I need this table? I've seen the hibernate.cfg.xml file, which looks like a good place to start.
You need to specify "create" for the "hibernate.hbm2ddl.auto" property. Read more details here. This is not recommended in production but only for testing purposes.
As for adding a new column to the table
As long as it is not a not null column you don't need drop the table or restart your hibernate app
If you do want to use the column then you need to map the column in the code/hbm file, so you will have to restart the hibernate app
If there is no mapping present as far as hibernate is concerned the column does not exisist, If it is a not null column then underlying data base would reject inserts/updates as hibernate will not include the column in generated sql
from hibernate documentation
hibernate.hbm2ddl.auto
Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.
e.g. validate | update | create | create-drop
hibernate Configuration

Why Hibernates ignores the name attribute of the #Column annotation?

Using Hibernate 3.3.1 and Hibernate Annotations 3.4, the database is DB2/400 V6R1, running that on WebSphere 7.0.0.9
I have the following class
#Entity
public class Ciinvhd implements Serializable {
#Id
private String ihinse;
#Id
#Column(name="IHINV#")
private BigDecimal ihinv;
....
}
For reasons I can't figure, Hibernate ignores the specified column name and uses 'ihinv' to generate the SQL:
select
ciinvhd0_.ihinse as ihinse13_,
ciinvhd0_.ihinv as ihinv13_,
...
Which of course gives me the following error:
Column IHINV not in table CIINVHD
Edit: I switched the log level of hibernate to DEBUG, and I see that it does not process the column annotation for that field. Tried several random things it just doesn't work.
Did anyone had this problem before? I have other entities that are very alike in the way that they are using # in their database field names and that are part of the PK and I don't have this problem with them.
You could try some kind of quoting:
For example:
#Column(name="`IHINV#`")
or
#Column(name="'IHINV#'")
Another option would be to dig in to source code Hibernate dialect for DB2 and see if it contains anything helpful.
Of course, the easiest way would be to remove the hash from column name if possible.
I suspect that the problem is the hash in the column name. A similar question on the hibernate forums suggests that backticks can be useful here.

Categories

Resources