I have a oracle table which contains char(n) type for several columns. I use hibernate tools to create entities objets and this tool map char type in String.
But when I deploy my application, I get an error because Hibernate wait a varchar2 type and not a char type:
Wrong column type in ARBOR.CMF for column CHG_WHO. Found: char, expected: varchar2(30 char)
What kind of java type must I use to map char(n) type in an entity ?
Thanks.
There's some useful information here on this blog entry.
Essentially you need to make your hibernate configuration more specific, as it's assuming a default String mapping to varchar2(30).
You can try using the database-agnostic annotation of #Column(length=N) (where N is the actual length of your column in the database). If that doesn't work, try using the #Column(columnDefinition = "char") approach.
Doesn't work - fails Hibernate schema validation:
#Column(name="ENABLED_FLAG", length=1)
private String enabledFlag;
Does work, since the columnDefinition attribute tells Hibernate not to default to VARCHAR2 as the column type, and to use CHAR instead:
#Column(name="ENABLED_FLAG", length=1, columnDefinition="CHAR")
private String enabledFlag;
The column in the database is defined as:
ENABLED_FLAG CHAR(1 BYTE)
Related
I have a table with an Enum type attribute mapped like this:
#Enumerated(EnumType.ORDINAL)
#Column(name = "status")
private Enums.Status status;
Where the Enums.Status is
public enum Status {
CHECKED(1),
DISABLED(2),
INACTIVE(3);
int id;
// constructor + getter
}
And the column status from the database is stored as type int4
I am querying the table with the following HQL:
Query q = session.createQuery(" from Users where status=:account");
query.setParameter("account", Enums.Status.CHECKED);
List<Users> users = query.list();
The above code works fine on my testing server, but when on the production server it throws the following exception:
org.hibernate.exception.DataException: Bad value for type int : t
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:134)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractResultSetProxyHandler.continueInvocation(AbstractResultSetProxyHandler.java:108)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy30.getInt(Unknown Source)
at org.hibernate.type.EnumType$OrdinalEnumValueMapper.getValue(EnumType.java:358)
at org.hibernate.type.EnumType.nullSafeGet(EnumType.java:105)
at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:127)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:106)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2873)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1668)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1600)
at org.hibernate.loader.Loader.getRow(Loader.java:1500)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:712)
at org.hibernate.loader.Loader.processResultSet(Loader.java:940)
at org.hibernate.loader.Loader.doQuery(Loader.java:910)
I tried replacing the enum parameter with its .ordinal() value, but received another exception. I tried looking up the differences between the testing server and the production server, but they both use the same java version, hibernate library, datatypes for the table and table content.
Has anyone ever encountered any similar issue or has any idea how it could be fixed?
I have figured out the problem. In our case the production server has multiple schemas and a database update failed on one of them, resulting in a field having a different data type then its hibernate mapping.
In case anyone gets here looking for an answer to the same error, try the following:
For enums, verify that the datatype in the db is integer for mapping #Enumerated(EnumType.ORDINAL) (or varchar for EnumType.STRING)
Verify that all other data types of that table match the hibernate mapping
Verify that the values inside the db do not exceed the number of items in the enum
Verify data in all schemas (if you are using multiple)
If you are experiencing this error on one server and not on another, check for the following differences: jdk version, hibernate-core version, database driver version. If they are all the same, try dumping the database from one server to another
With Java Enums, the term ordinal does not refer to an id property, but to a built in property of the Enum class. See JavaDocs for the ordinal() method.
Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero). Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data structures, such as EnumSet and EnumMap.
Note that the first ordinal is 0 (zero) not 1
Don't be calling the ordinal() method yourself; let Hibernate do that.
I was generating Entity class using JPA Tools in eclipse Mars. It generates data member of Integer datatype which is smallint type in table.I need to generate short type of datatype for column which is smallint in table.
I think something like this might work :-
#Column(columnDefinition = "SMALLINT")
#Type(type = "org.hibernate.type.ShortType")
private short variableName;
After entering JPA entities from table wizard after selecting table->table Association->Customize Defaults->customize indicidual Entities .. here you can customize your table
But usually it ll automatically convert smallint type to short.
I have to store long strings in MySQL database using spring roo. I assumed that "field string" command generates field with size 255 which is too small. I prefer to not use blob. What should I do?
If you create the field using a command like field string --fieldName field1 --sizeMax 500 then Roo will annotate the field with #Size(max = 500) and it works for me if I let Hibernate to create the database schema.
(--sizeMax is an optional parameter, you can display all optional parameters after you defined all mandatory ones with -- and hitting TAB)
Another solution is to add manually the JPA annotation on the field: #Column(length=500).
Or if you don't generate the database schema but create it by hand then you can define your column as you like.
How can I declare within an Entity Bean a Long Text attribute?
For example: String description
I would like it to be more than 255 varchar, and maybe mapped on MySQL as TEXT.
Thanks
Solved:
JPA: how do I persist a String into a database field, type MYSQL Text
Using #Lob annotation
Just define the corresponding column in database as TEXT, and JPA should happily map the column to your attribute.
Is there a class that I could use in Hibernate so that I could pass in a class and it would return the appropriate database type name?
For example,
String type = HibernateTypeGod.getTypeName(String.class);
Hibernate would determine the dialect I specified and return me VARCHAR2 in the case of Oracle.
It's not that easy. All the mapping stuff is in the classes Configuration, Table, Column and Dialect, so you will need some kind of valid config to query this from Hibernate. But you can for example use:
String s = myDialect.getTypeName(sqlType,length,precision,scale);
Of course you need to find the dialect and the sqlType, but this isn't fixed in Hibernate on a class basis, but can be configured per column anyway, so what is the reason to ask by Class and not by column name?