JPA: "Column not found" although JPA created the table - java

I am trying to test a batch reading data from a database.
I have an entity such as:
#Entity
#Table(name = "CLIENT")
public class ClientEntity {
#Id
#Column(name = "ID")
private Long id;
#Column(name = "START", nullable = false)
#Temporal(TemporalType.DATE)
private Date start;
}
When unit testing my batch, I insert data into a memory database thanks to a SQL script read with the hibernate.hbm2ddl.import_files option while the hibernate.hbm2ddl.auto option is set on create:
Insert into CLIENT(ID, START) values (1,'2006-02-01')
Insert into CLIENT(ID, START) values (2,'2010-02-01')
I can see in the log that the table is properly created. Yet, when retrieving the CLIENTs further in my code (perhaps through some join), an exception is raised:
ERROR - Column "CLIENTENTI0_.START" not found; SQL statement:
select cliententi0_.ID as ID1_10_, cliententi0_.START
as START2_10_ from CLIENT cliententi0_ [42122-165]
I have to add that when plugged to an exising Oracle database, the code runs perfectly!
What is wrong with my code? How can I get it to work?
Thanks for your help!

Well shame on me.
The error came from the fact that the goal of my batch is reading data from a database A and to write data to a database B.
To test my batch, I set two memory instances. But a mistaken copy and paste made me create twice the same instance... And since there is one CLIENT table in A and one other CLIENT table in B, an error was raised when retrieving the data: one of those tables was unproperly created!
Hope this might help someone else!

Related

Hibernate Generation Type for SQL Server and Others

I wrote program that uses different databases like sql server, oracle etc. My problem is that I can't handle GenerationType and insert correct row into table. Using GenerationType.AUTO and hibernate.id.new_generator_mappings := false in sql server, my program is able to insert new row into table, but ID is always null, same problem is when GenerationType is IDENTITY.
I tried to add auto-incrementation only for sql server, but Liquibase yells at me that it's not supported for mssql. When I use Sequences for Oracle as well SQL Server my program is trying to get "next value" from generator but it cannot and do infinite loop. Even if I set default value for ID it won't increment this value.
Thats my code :
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "name")
#SequenceGenerator(name = "name", sequenceName = "SEQ", allocationSize = 1)
private Long id;
I would like to be able to add auto-incrementing indices into table and it should work for SQL Server databases and I don't want to use Table strategy for generation because it needs additional table in db.
Problem solved. I add condition in Liquibase xml file that checks whether db is mssql type and if it's true script drops ID column and adds it with IDENTITY(1,1) option.
The only problem is that now I have to switch aforementioned "hibernate.id.new_generator_mappings" setting.

How to get length of CLOB in Java/Hibernate

I am working with a table (Oracle), that has a CLOB column. And I am using Hibernate to query the table. Here is a quick look at the class that I am using to map the Oracle table:
#Entity
#Table(name="D2D_OPD_ORDERDELIVERY")
public class D2dOpdOrderDelivery implements Serializable {
// other column mappings omitted for brevity
#Column(name="POD_SIGNATURE_IMG", nullable=true)
#Lob
private Clob podSignatureImage;
I have successfully managed to run the Hibernate query, which returns a single row from the database:
// Create a Hibernate query (HQL)
Query query = session.createQuery("FROM D2dOpdOrderDelivery WHERE orderNumber = :orderNumber");
query.setParameter("orderNumber", orderNumber);
Elsewhere in my code, I perform a null check on my Clob - it is NOT null. Next, I try to get the length of my Clob. And this is where I run into a problem. I get the following error:
java.sql.SQLException: Closed Connection
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:147)
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:209)
oracle.sql.CLOB.getDBAccess(CLOB.java:1212)
oracle.sql.CLOB.length(CLOB.java:223)
Sorry, I just don't understand why I am getting this error. I have already run my query (all the other fields in the row are present). Why can't I get the length of my CLOB?
Can someone please point out where I have gone wrong?
Thank you.
OK, after posting this question, I went back and searched the Internet some more. I thought I had done a pretty good job of that before I posted my question - but that is another matter...
Anyway, I found a useful link here:
http://www.javavids.com/video/how-to-read-data-from-blob-using-jpa-hibernate.html
And the change I made to my code:
#Column(name="POD_SIGNATURE_IMG", nullable=true)
#Lob
#Basic(fetch=FetchType.LAZY)
private char[] podSignatureImage;
I was then able to call .length on my char[]
Hope this is helpful to someone else...

H2 Database simulate Oracle XMLtype - Hibernate

I have the following column in one of my hibernate entities:
#Lob
#Basic(fetch=FetchType.LAZY)
#ColumnTransformer(read = "to_clob(xmlContent)", write = "?")
#Column(name="XMLCONTENT", updatable = false, columnDefinition = "XMLType")
private String xmlContent;
However when I have hibernate.hbm2ddl.auto = create on hibernate it fails to create the particular table giving me the following error:
Unknown data type: "XMLTYPE"; SQL statement:
So basically I can't include this table/entity at all in tests with the H2 database. I need to have an XE at least installed.
Is there any workaround/solution to this, possibly another in memory database supports this?

Force hibernate to leave id empty

So I am using Postgres and Hibernate 4.2.2 and with entity like this
#Entity(name = "Users")
#Check(constraints = "email ~* '^[A-Za-z0-9._%-]+#[A-Za-z0-9.-]+[.][A-Za-z]+$'")
#DynamicInsert
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_user",unique = true)
#Index(name = "user_pk")
private Integer idUser;
Hibernate still inserts some id that is already in the table, instead of leaving it emtpy for the database to fill it in. Also hibernate forces ids based on its cache not even checking the database whether it has the lates id.
How can I force it so I can leave id blank and let the database insert it?
First I thought it was because I was using int and that int is by default 0 but even when using object it just forces the id there from its cache.
So my goal is to let the database fill the ids instead of hibernate or at least Hibernate before filling it in to check the database for id first.
So the error I was getting wasCaused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "users_pkey" Detail: Key (id_user)=(1) already exists.
And it wasn't caused by Hibernate and caching but by import of data at creation of database, where I inserted with given ids eg: INSERT INTO users(id_user,email,password,tag) VALUES (1,'a#b.c','***','Adpleydu');
and the sequence for generating wasn't updated so if I inserted with pure SQL via console I got the same error.
Seeding the data is the problem. However you can still seed with pure sequal and have the sequence "keep up".
1) Assure your primary key is of type SERIAL.
CREATE TABLE table_name(
id SERIAL
);
2) Add this 'setval' line to assure the sequence is updated.
select setval('table_name_id_seq',COALESCE((select max(id) + 1 from table_name), 1));
Reference:
https://www.postgresqltutorial.com/postgresql-serial/

"No row with the given identifier exists" although it DOES exist

I am using Hibernate and getting
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [#271]
What is pretty weird about this error is, that the object with the given id exists in the database. I inserted the problematic record in another run of the application. If I access it in the same run (i.e. same hibernate session) there seem to be no problems retrieving the data.
Just because it could be a fault of the mapping:
public class ProblemClass implements Persistent {
#ManyToOne(optional = false)
private MyDbObject myDbObject;
}
public class MyDbObject implements Persistent {
#OneToMany(mappedBy = "myDbObject")
private List<ProblemClass> problemClasses;
#ManyToOne(optional = false)
private ThirdClass thirdClass;
}
I have absolutely no clue even where to look at. Any hints highly appreciated!
Just to clarify:
The data was inserted in another RUN of the application. It is definitely in the database, as I can see it via an SQL-Query after the application terminated. And after THAT, i.e. when starting the application again, I get the error in the FIRST query of the database -- no deletion, no rollback involved.
Addition:
Because it was asked, here is the code to fetch the data:
public List<ProblemClass> getProblemClasses() {
Query query = session.createQuery("from ProblemClass");
return query.list();
}
And just to make it complete, here is the generic code to insert it (before fetching in another RUN of the application):
public void save(Persistent persistent) {
session.saveOrUpdate(persistent);
}
Eureka, I found it!
The problem was the following:
The data in the table ThirdClass was not persisted correctly. Since this data was referenced from MyDbObject via
optional = false
Hibernate made an inner join, thus returning an empty result for the join. Because the data was there if executed in one session (in the cache I guess), that made no problems.
MySQL does not enforce foreign key integrity, thus not complaining upon insertion of corrupt data.
Solution: optional = true or correct insertion of the data.
Possible reasons:
The row was inserted by the first session, but transaction was not committed when second session tried to access it.
First session is roll-backed due to some reason.
Sounds like your transaction inserting is rollbacked
Main reason behind this issue is data mismatch, for example i have entity mapping class called "X" and it has column "column1" and it has reference to the table "Y" column "column1" as below
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "column1", referencedColumnName = "column1")
public Y getColumn1() {
return Y;
}
In this if X table column1 has value but Y table column1 is not having the value. Here link will be failed.
This is the reason we will get Hibernate objectNotFound exception
This issue can also be resolved by creating proper data model like creating proper indexing and constraints (primary key/foreign key) ..
This might be your case, kindly check my answer on another post.
https://stackoverflow.com/a/40513787/6234057
I had the same Hibernate exception.
After debugging for sometime, i realized that the issue is caused by the Orphan child records.
As many are complaining, when they search the record it exists.
What i realized is that the issue is not because of the existence of the record but hibernate not finding it in the table, rather it is due to the Orphan child records.
The records which have reference to the non-existing parents!
What i did is, find the Foreign Key references corresponding to the Table linked to the Bean.
To find foreign key references in SQL developer
1.Save the below XML code into a file (fk_reference.xml)
<items>
<item type="editor" node="TableNode" vertical="true">
<title><![CDATA[FK References]]></title>
<query>
<sql>
<![CDATA[select a.owner,
a.table_name,
a.constraint_name,
a.status
from all_constraints a
where a.constraint_type = 'R'
and exists(
select 1
from all_constraints
where constraint_name=a.r_constraint_name
and constraint_type in ('P', 'U')
and table_name = :OBJECT_NAME
and owner = :OBJECT_OWNER)
order by table_name, constraint_name]]>
</sql>
</query>
</item>
2.Add the USER DEFINED extension to SQL Developer
Tools > Preferences
Database > User Defined Extensions
Click "Add Row" button
In Type choose "EDITOR", Location - where you saved the xml file above
Click "Ok" then restart SQL Developer
3.Navigate to any table and you will be able to see an additional tab next to SQL, labelled FK References, displaying FK information.
4.Reference
http://www.oracle.com/technetwork/issue-archive/2007/07-jul/o47sql-086233.html
How can I find which tables reference a given table in Oracle SQL Developer?
To find the Orphan records in all referred tables
select * from CHILD_TABLE
where FOREIGNKEY not in (select PRIMARYKEY from PARENT_TABLE);
Delete these Orphan records, Commit the changes and restart the server if required.
This solved my exception. You may try the same.
Please update your hibernate configuration file as given below:
property start tag name="hbm2ddl.auto" create/update property close tag
I have found that in Oracle this problem can also be caused by a permissions issue. The ProblemClass instance referred to by the MyDbObject instance may exist but have permissions that do not allow the current user to see it, even though the user can see the current MyDbObject.

Categories