I'm currently migrating some existing code from Hibernate 3.2 to Hibernate 3.6.10.Final
(and also from Spring 2.0 to Spring 3.1.2 by the way).
I have an issue with some integration tests running against H2 database, verifying that some fields are not nullable.
- I test that an attempt to insert a null String into a field marked as nullable=false ends with an Exception
- I checked that the schema is correctly created : the column is not nullable.
Using H2 (with MySQL mode), nullable constraint is ignored : an empty String is inserted in database.
I don't reproduce the case if I run my test against a MySQL database.
It worked before with Hibernate 3.2
For example, if I have a class Person :
#Entity
class Person {
#Id
#GeneratedValue
private Long id;
#Column(nullable=false)
private String name;
//getters and setters
}
And then I have a test (still using JUnit3, I'll migrate this later) :
#ExpectedException(value=DataIntegrityViolationException.class)
public void testPerson_NameCantBeNull() throws Exception {
// Given
Person person = new Person();
person.setName(null);
// When
getHibernateTemplate().persist(person);
//Flush and clear session
}
I could fix this by replacing nullable=false by #NotNull annotation but I don't want to replace it in my huge code base as I wouldn't expect the same Exception.
I had a quick look into H2Dialect class and JIRA issues in Hibernate but I didn't find anything.
Does anybody know where it comes from ?
EDIT :
Some additional informations, I added the TRACE level in Hibernate logs.
When I insert null and the field is marked with #Column(nullable=false), I have the following log :
2013-01-16 15:57:52 TRACE [BasicExtractor] found [] as column [NAME1_3_]
When I insert null and the field is not marked with #Column(nullable=false), I have the following log :
2013-01-16 15:57:52 TRACE [BasicExtractor] found [null] as column [NAME1_3_]
EDIT (22/01/13) :
I still didn't found where the problem exactly come from, but I found out that it is tied to MySQL mode with H2 : if I disable MySQL mode, Hibernate doesn't try anymore to replace my null Strings by empty Strings.
But I can't do this since some other pieces of code are tied to MySQL syntax.
Any idea ?
I didn't have enough time to digg in Hibernate and MySQL dialect, so I moved to Java Validation Framework, using #NotNull annotation.
It does the job and meets one of our other requirement : a part of our model is used in a Grails application and we want to use constraints to validate part of CRUD operations (not possible with pure javax.persistence annotations).
Related
i have spring boot application that uses my database schema. Lets say i have non-empty schema with table APPLICATION_USERS defined as follows:
create table AREA
(
name NVARCHAR2(36) not null,
id NUMBER not null
)
now i wanted to add FlyWay to my application. I have defined in my application properties flyway.baselineOnMigrate=true to start initial Flyway deployment and spring.jpa.hibernate.ddl-auto=validate to validate my Enities agains schema, however upon starting application i get following error:
wrong column type encountered in column [name] in table [APPLICATION_USERS]; found [nvarchar2 (Types#OTHER)], but expecting [varchar2(255 char) (Types#VARCHAR)]
as far as i understand it, it complains about NVARCHAR2, as it expect varchar how can i force hibernate to accept nvarchar2 as varchar?
i know i can use columnDefinition on my entity attributes, however this is not my dream solution, is there any other way?
I assume that you are using Oracle database.
You have to annotate your the attribute name in your Entity with Nationalized
#Nationalized
private String name;
You also could register your own dialect:
public class CustomOracleDialect extends Oracle10gDialect {
public CustomOracleDialect() {
super();
registerColumnType(Types.NVARCHAR, "nvarchar2($l)");
registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
}
}
I'm trying make an entity work with Oracle (11.2) and PostgreSQL(9.4) in a Spring Boot (1.4.4) application.
My entity contains a long text field (over 4000 characters).
The appropriate data type in Oracle is CLOB and the corresponding type in PostgreSQL is TEXT.
I'm able to make it work with PostgreSQL
#Column(name = "LONG_TEXT", columnDefinition="TEXT")
private String longText;
However it would fail with Oracle in hibernate validation stage since CLOB requires #Lob annotation.
The following code works with Oracle
#Lob
#Column(name = "LONG_TEXT")
private String longText;
However this time it fails when reading from PostgreSQL with the following exception:
PSQLException: Large Objects may not be used in auto-commit mode
Stack overflow suggests performing queries in transactions. Disregarding questionable requirement to invoke transaction in select queries, adding #Transactional to query methods didn't help.
Any thoughts are more than welcomed.
The solution we came to is to adopt the #Lob and #Transactional approach.
The main issue was with the placement of the #Transactional annotation, causing the PSQLException. Once fixed, we were able to work with both types of DBs.
I use hibernate in an application with spring boot 1.4.0.RELEASE.
The Entity for the index looks something along the lines of:
#Entity(name = "SearchableTariffItem")
#Indexed
public class SearchableTariffItem {
public static final String ZIFFER_ANALYZER_NAME = "ZIFFER_ANALYZER";
#GeneratedValue(strategy = GenerationType.TABLE)
#Id
private Long id;
...
}
I now get the following warning when I save the entity for the first time:
2016-08-26 15:08:32.501 WARN 8476 — [apr-8080-exec-6] org.hibernate.orm.deprecation : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead. See Hibernate Domain Model Mapping Guide for details.
Unfortunately I don't know where I can configure my application (preferably in a the application.yml) to use the TableGenerator class.
I use the following dependency:
Hibernate core 5.0.9.Final
Hibernate search ORM 5.5.1.Final
Lucene 5.3.1
The property that controls this behaviour in Hibernate is hibernate.id.new_generator_mappings, which defaults to true for Hibernate 5 -> which means the new TableGenerator will be used instead of the deprecated MultipleHiLoPerTableGenerator .
Spring Boot however defaults this property to false, which means the old generator will be used, unless you explicitly tell it you want the new one.
You need to set the property spring.jpa.hibernate.use-new-id-generator-mappings to true to get the TableGenerator.
See https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#generator-mappings
Similar to this problem:
ORA-00904: : invalid identifier Issue with Hibernate Dependent objects program
I'm trying to do batch inserts using hibernate. Whenever I try to do a session.save or session.saveOrUpdate, hibernate complains that I have an invalid identifier
Stack output
2015-11-20 14:17:37 ERROR : ORA-00904: "USERATTRID": invalid identifier
Entity
public class Attribute {
#Id
#GenericGenerator(name = "increment", strategy = "increment")
#GeneratedValue(generator = "increment", strategy = GenerationType.SEQUENCE)
private int USERAttrID;
private long userNumber;
private String attribute;
private String value;
private String description;
private LocalDateTime updatedDate;
private LocalDateTime createdDate;
The database looks like this after hibernate applies its improved naming convention
USER_ATTRID
ATTRIBUTE
USER_NUMBER
DESCRIPTION
VALUE
CREATED_DATE
UPDATED_DATE
If I use repository.save then the code works fine. The crud repository seems to know how to map my entity to the database, but hibernate's session does not.
I see a few solutions here:
1. Use hibernate's default default naming strategy. Tables get named things like USERATTRID. I'm not sure what implications this has other than making columns harder to read.
2. Combine hibernate with crudrepository using the tutorial here
http://frightanic.com/software-development/jpa-batch-inserts/
3. Figure out how to get hibernate's session.save to use the improvedNamingConvention mapper. Can anyone help me with this or provide me another suggestion?
4. I guess I can also manually map the columns :/. Ugh this is messy, you now have to manually do all the conversions on dates :/
It would be good to know how you are actually getting the session?The most likely cause that comes to mind is that when you using the hibernate session it is actually not built using the same configuration that was used to build the entity manager that CrudRepository uses underneath.
Ends up being more trouble than it's worth as you stop using hibernate jpa's defaults and all the things spring-data provides you out of the box
Stupid. The tutorial doesn't even use crudRepository
Same as 1
Same as 1
Instead I'm banging my head against a wall trying to get a simple batch process to insert
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.