Java Hibernate DataException: cannot be converted to BIGINT - java

I'm trying to join one table, with two other tables, using a single column in Java using Hibernate and JPQL.
For example, I have table A with an id column. I want to join table B and table C with table A on the id column.
However, when I try to do that I get the following error:
org.hibernate.exception.DataException: The value supplied cannot be converted to BIGINT. I have seen some answer say that there may be null values, but these id columns are primary id columns, and contain no nulls.
My code is as follows:
#OneToOne(fetch = fetchType.LAZY)
#JoinColumn(name="id", insertable=false, updatable=false)
private TableB tableB
#OneToOne(fetch = fetchType.LAZY)
#JoinColumn(name="id", insertable=false, updatable=false)
private TableC tableC
When I remove one of the two joins everything works fine again.
What am I doing wrong that's causing this issue?

I don't know what type id is, but is but I think it must be a Long in order for Hibernate to convert it to a BIGINT

Related

Hibernate select id of join column without join

The problem is I need to select an object from database which has a join column inside, and I need the Id of that foreign object. But hibernate joins those two tables or if in lazy mode , It queries again on my database.
How do I access that Id with no other join or query than the primary select query.
Note that I am using Hibernate version +5 and I want an approach via JPA CriteriaBuilder.
Thank you in advance.
You can map the foreign key to the entity twice in this case, one for actual ORM and another for getting the FK without actually firing a new query.
public class Answer {
#JoinColumn(name = "question_id")
#ManyToOne(targetEntity = Question.class, fetch = FetchType.LAZY)
private Question question;
#Column(name = "question_id", insertable = false, updatable = false)
private Long questionId;
}
Here question_id is present in the answer table.
This way that foreign key will be already available in the result of the first query(in the questionId field) and the new query won't be fired for getting the FK value.

JPA secondary table as read only view - hibernate still tries to insert rows

I've got the following entity:
#Entity
#Table(name = "ONE")
#SecondaryTable(name = "VIEW_TWO", pkJoinColumns = #PrimaryKeyJoinColumn(name="ONE_ID"))
public class CpBracket {
#Id
private Long id;
#Column(name="progress", table="VIEW_TWO", updatable = false, insertable = false)
private int progress = 0;
(...)
}
As you see, this entity uses table ONE and (read only) view VIEW_TWO. When I'm persisting the entity, hibernate is performing insert into view:
insert into VIEW_TWO (ONE_ID) values (?)
It is ignoring the non-updatable and non-insertable column progress (that's good) and it is still trying to insert value of ONE_ID column. As far as I know, the annotation #PrimaryKeyJoinColumn marks selected column as insertable=false and updatable=false.
How can I prevent hibernate from inserting rows into secondary table (view)?
As far as I know, the annotation #PrimaryKeyJoinColumn marks selected
column as insertable=false and updatable=false.
I do not believe this can be the case: how then do we get records inserted into the #SecondaryTable when it is an actual table rather than a view?
As neither #SecondaryTable or #PrimarykeyJoinColumn have a means to prevent insert then it would appear that your original solution is not going to work and an alternative is required.
One option is to map VIEW_TWO as an #Entity and link to your class CPBracket as a #OneToOne relationship with cascade options set to none.
#Entity
#Table(name ="VIEW_TWO")
private CpBracketSummaryData(){
}
#Entity
#Table(name = "ONE")
public class CpBracket {
#OneToOne
#PrimaryKeyJoinColumn
private CPBracketSummaryData summaryData;
public int getSomeValue(){
return summaryData.getSomeValue();
}
}
The second option would be to use the non JPA compliant, Hibernate specific #Formula annotation.
#Entity
#Table(name = "ONE")
public class CpBracket {
#Formula("native sql query")
private int someValue;
}
Update October 2016
I have revisited this in both Hibernate 4.3.10.Final and 5.1.0.Final and it is possible to have the view as a #SecondaryTable without the insert: if you have the correct mappings.
Scenario 1
Load an entity for edit and do not touch any fields mapped to the secondary table. No update is issued to the secondary table
Scenario 2
Create and save a new entity and do not set any fields mapped to the secondary table. No insert is issued for the secondary table
Scenario 3
Create or update an entity including a field mapped to a secondary table and where this field is marked as insertable = false and updateable = false. An insert is made to the secondary table only for the ID field -the behaviour reported in the original question.
The issue with the mapping in the original question is the fact that the secondary table field is a primitive type and therefore when saving a new entity Hibernate does think a record has to be written to the secondary table with a value of zero.
#Column(name="progress", table="VIEW_TWO", updatable = false, insertable = false)
private int progress = 0;
The solution then is to replace primitives with the corresponding wrapper types and leave them as null. Then when saving a new record there is nothing to write to the secondary table and no insert will be made:
#Column(name="progress", table="VIEW_TWO")
private Integer progress;
I solved a similar problem with #SecondaryTable, which was a database view. So maybe it will help someone else.
The problem was on cascade delete to #SecondaryTable, when record from primary table was deleted.
As a solution, I implemented RULE on view for delete
CREATE RULE on_delete AS ON DELETE TO my_view DO INSTEAD(
select 1;
)
Similar solution can be used for INSERT and UPDATE operation on view.

When Should I Use #JoinColumn or #JoinTable with JPA?

#JoinColumn gives an Entity a foreign key to another Entity whereas #JoinTable will list the relationship between all relationships between Entity A and Entity B. As far as I can tell, they both appear to do similar things. When should I use one or the other?
Let's say you have an entity A which has a #ManyToOne association ot an entity B
#JoinColumn will define the target table Foreign Key (e.g B_ID) while using the target Entity table (e.g. B).
#Entity
public class A {
private Long id;
#ManyToOne
#JoinColumn(name="B_ID")
private B b;
}
#JoinTable will use a separate table to hold the relationship between A and B.
#Entity
public class A {
private Long id;
#ManyToOne
#JoinTable(
name = "A_B",
joinColumns = #JoinColumn(name = "B_ID"),
inverseJoinColumns = #JoinColumn(name = "A_ID")
)
private B b;
}
This time neither A nor B contain any Foreign Key, because there's a separate table (e.g. A_B) to hold the association between A and B.
#JoinTable stores the id of both the table into a separate table while #JoinColumn stores id of the another table in a new column.
#JoinTable : This is the default type. Use this when you you need a more normalized database. ie. to reduce redundancy.
#JoinColumn : Use this for better performance as it does not need to join extra table.
one important difference: #JoinColumn always depends upon the context it is used:
If the join is for a OneToOne or ManyToOne mapping using a foreign key mapping strategy, the foreign key column is in the table of the
source entity or embeddable.
If the join is for a unidirectional OneToMany mapping using a foreign key mapping strategy, the foreign key is in the table of
the target entity.
If the join is for a ManyToMany mapping or for a OneToOne or bidirectional ManyToOne/OneToMany mapping using a join table, the
foreign key is in a join table.
If the join is for an element collection, the foreign key is in a collection table.

How do I create an index on join tables using Hibernate annotations?

I have a relationship as follows using Hibernate annotations, this is what I tried:
public class Job{
...
#OneToMany(cascade = CascadeType.ALL)
#JoinTable(name = "jobs_resource_locations")
#ForeignKey(name = "job_inputs_fk")
#Index(name="job_inputs_fk")
private List<FileSystemLocation> inputs;
This sort of thing works nicely on ManyToOne like so:
#ManyToOne
#JoinColumn(name = "service_call_id", referencedColumnName = "id")
#ForeignKey(name = "job_service_call_fk")
#Index(name = "job_service_call_fk")
private ServiceCall serviceCall;
I wanted to ensure that the foreign key gets indexed on PostgreSQL and that the schema looks similar on MySQL, hence the #ForeignKey and #Index with the same name (MySQL always creates an index with the same name as the FK).
I cannot create the index on the inverse side because FileSystemLocation is unaware of the relationship. Hence the JoinTable.
The former example fails since Hibernate finds no column in Job to index:
org.hibernate.MappingException: Unable to find logical column name from physical name null in table jobs
Does anyone know how to create indices on JoinTable foreign keys using Hibernate?
It's not exactly the answer you would like to receive, but this is the expected behavior. In other words: this is not supported. See the following JIRA for more details:
https://hibernate.atlassian.net/browse/HHH-4263

How can I ask Hibernate to create an index on a foreign key (JoinColumn)?

Here is my model:
class User {
#CollectionOfElements
#JoinTable(name = "user_type", joinColumns = #JoinColumn(name = "user_id"))
#Column(name = "type", nullable = false)
private List<String> types = new ArrayList<String>();
}
As you can imagine there would be a table called "user_type", which has two columns, one is "user_id" and the other is "type".
When I use hbm2ddl to generate the ddls, I want to have this table, along with the foreign key constraint on "user_id".
However, there is no index for this column. How can I get hibernate to generate the index for me?
Try an #Index annotation.
#Index(name="user_type_index")
There is also an #IndexColumn annotation used with join tables, but it doesn't seem to actually create an index, but controls which field defines order in list semantics.
The #Index column in this context does seem to create an index on the join table.
I'm dealing with a similar issue and I've found that some dialects will automatically index foreign keys and others wont.
Hibernate Dialect class and all subclasses which do not override the getAddForeignKeyConstraintString method (Oracle, SQL Server, etc) will not create an index on the foreign key.
MySQLDialect overrides that method and adds an index to every foreign key

Categories