Invalid Identifier While Joining Tables in JPA - java

I am trying to join 3 tables in JPA. When i am trying to associate CRL_IC_IMPORT_TRANS table i am getting error as Invalid Identifier as shown below
from
crl_ic investorco0_
left outer join
crl_ic_import_trans icimporttr1_
on investorco0_.icimport_trans_event_id=icimporttr1_.event_id
left outer join
crl_ic_order investorco2_
on investorco0_.current_order_id=investorco2_.id
"INVESTORCO0_"."ICIMPORT_TRANS_EVENT_ID": invalid identifier
Edit
from
crl_ic investorco0_
left outer join
crl_ic_order investorco1_
on investorco0_.current_order_id=investorco1_.id
Error:
Provided id of the wrong type for class ICImportTrans. Expected: class java.lang.Long, got class java.lang.String
Why its going to primary key in ICImportTrans class even after i mapped to a non PK ?
Below are my 3 tables and its keys. What is the mistake i am doing .
#Table(name = "CRL_IC")
public class ICLoanOrder {
#Id
#Column(name="EVENT_ID")
String id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "EVENT_ID",referencedColumnName = "eventId" )
ICImportTrans iCImportTrans;
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
ICOrder currentOrder;
}
#Table(name = "CRL_IC_ORDER")
public class ICOrder implements Serializable {
#Id
#GenericGenerator(name = "UUIDGenerator", strategy = "uuid2")
#GeneratedValue(generator = "UUIDGenerator")
#Type(type = "uuid-char")
UUID id;
#ManyToOne(fetch = FetchType.LAZY)
#JsonIgnore
#JoinColumn(name="EVENT_ID")
ICLoanOrder iCLoanOrder;
}
#Table(name = "CRL_IC_IMPORT_TRANS")
public class ICImportTrans implements Serializable {
#Id
#GeneratedValue(strategy= GenerationType.SEQUENCE, generator="SEQ1")
#SequenceGenerator(name="SEQ1",sequenceName = "SEQ_IC_IMPORT",allocationSize = 1)
#Column(name="PROCESS_ID")
private Long processId;
private String eventId;
}

The default name of the column should be iCImportTrans_id.
If you want to change it to icimport_trans_event_id you need to specify it in the #JoinColumn
#Table(name = "CRL_IC")
public class ICLoanOrder {
...
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "icimport_trans_event_id", referencedColumnName = "eventId")
ICImportTrans iCImportTrans;
...
}
Provided id of the wrong type for class ICImportTrans. Expected: class java.lang.Long, got class java.lang.String
What kind of mapping are you trying to achieve?
In ICLoanOrder you mapped the id column and the association column to the same name EVENT_ID. I guess you want to use ICImportTrans.eventId as id of ICLoanOrder.
This willwork if you don't care about having an id field:
#Entity(name="LoanOrder")
#Table(name = "CRL_IC")
public static class ICLoanOrder implements Serializable{
#Id
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "EVENT_ID", referencedColumnName = "eventId")
ICImportTrans iCImportTrans;
}
Normally, you would use #MapsId, but it seems to ignore the referencedColumn attribute and gives the same error.

Related

Hibernate: Two Foreign key as ids

I have defined a many-to-one relationship between my three entity classes catalogB, tableA and tableAB. tableAB has a primary key composite of tableA.tableAId and catalogB.catalogBId, and I used the following code:
#Entity
#Table(name = "tableAB", schema = Constantes.SCHEMA_SOLICITUD,uniqueConstraints = {#UniqueConstraint(columnNames = { "tableAId ", "catalogBId" }) })
public class TableAB implements Serializable {
private static final long serialVersionUID = 6360131240770014903L;
#Id
#ManyToOne(optional = false)
#JoinColumn(name = "tableAId", referencedColumnName = "tableAId")
private TableAId tableAId;
#Id
#ManyToOne(optional = false)
#JoinColumn(name = "catalogBId", referencedColumnName = "catalogBId")
private CatalogBId catalogBId;
And that gives me an error:
Caused by: java.lang.IllegalArgumentException: This class [schema.TableAB ] does not define an IdClass
Refer this question. The accepted answer as well as other answers shed light on what you are trying to achieve.

What I need to write in JoinColumn?

Sorry for my question. Really can`t understand my mistake.
I have a Hibernate relations between two classes but when I run it logs give me this error:
org.hibernate.AnnotationException: mappedBy reference
an unknown target entity property: model.pilgi.Pilgi.PilgiDocument in model.pilgi_doc.PilgiDocument.pilgi
Code of the fisrt class PilgiDocument:
#Entity
#Table(name = "pilgi_document")
public class PilgiDocument {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private BigInteger pdocument_id;
#OneToMany(mappedBy = "PilgiDocument")
private List<Pilgi> pilgi = new ArrayList();
Pilgi class is here:
#Entity
#Table(name = "pilgi")
public class Pilgi {
#JoinColumn(name = "pilga")
#ManyToOne(fetch = FetchType.LAZY)
private PilgiDocument pdocument_id;
The error your have says that Hibernate doesn't find the PilgiDocument attribute in the class Pilgi: you don't have it but you have a pdocument_id property, that is an instance of PilgiDocument
In your PilgiDodument class, what you need to write is :
#Entity
#Table(name = "pilgi_document")
public class PilgiDocument {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private BigInteger pdocument_id;
#OneToMany(mappedBy = "pdocument_id")
private List<Pilgi> pilgi = new ArrayList();
You indicate the name of the attribute of your Pilgi class that represent the PilgiDocument attribute
In your Pilgi class, you need to write, in your #JoinColumn the name of the database column used as your foreign key for your PilgiDocument

JPA. Stackoverflow on cascade merge

Here is my JPA structure:
Movie (look at cascade types):
#Entity
#Table(name = "movie")
public class Movie {
#Id
#Column(name = "movie_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
//#OneToMany(cascade = CascadeType.ALL, mappedBy = "primaryKey.movie") //stack overflow
#OneToMany(mappedBy = "primaryKey.movie") //works fine
private List<Rating> ratings;
....
}
Rating:
#Entity
#Table(name = "rating")
#AssociationOverrides({#AssociationOverride(name = "primaryKey.movie", joinColumns = #JoinColumn(name = "movie_id")),
#AssociationOverride(name = "primaryKey.user", joinColumns = #JoinColumn(name = "imdb_user_id"))})
public class Rating {
#EmbeddedId
private RatingId primaryKey = new RatingId();
#Column(name = "rating_value")
private Integer ratingValue;
.....
}
RatingId:
#Embeddable
public class RatingId implements Serializable{
#ManyToOne
private Movie movie;
#ManyToOne
private User user;
}
When I call entityManager.merge(Movie movie) with CascadeType.ALL I get the StackOverflowError. If remove cascading, merge call doesn't throw the error. Where may be a problem?
I think this problem related to composite primary key. There is no error when merge performed on another entities with the same one-to-many relationship, but without composite id.
StackOverflow was caused by cyclic relations. To avoid exception I marked keys in many-to-many table as #ManyToOne(fetch = FetchType.LAZY).
That's how my tables look after modifications: https://stackoverflow.com/a/32544519/2089491

org.hibernate.PropertyAccessException while persisting ManyToMany relationship

Have a problem persisting a ManyToMany relationship mapped like that
Document.java
public class Document {
.......
#ManyToMany(targetEntity = Category.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "fideuram_gup_documents_in_categories",
joinColumns = #JoinColumn(name="fk_document"),
inverseJoinColumns = #JoinColumn(name = "fk_category"))
private Set<Category> categories = new HashSet<Category>();
.......
}
where Category is one more entity of my model which I don't paste here since it doesn't carry a reverse mapping of this relation, and has just an ID and a name.
When I try to persist Document however I get the following error:
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of it.ardesia.fideuram.gup.model.Category.id
I've surfed the web about it but no page relates to ManyToMany relations. Of course all the ManyToOne relations I have on the entity Document work fine.
I'm using:
spring-data-jpa:1.2.0.RELEASE
hibernate-core:4.2.2.Final
hibernate-entitymanager:4.2.2.final
UPDATE
All entities expose a default constructor and getter/setter for every field. Or,more preciselt, I'm using Spring Roo for creating the entity and it injects getters and setters automatically upon compilation.
You can instrument Hibernate how it must access your property using #javax.persistence.Access annotation; put on your mapped class with #Access.value set to
AccessType.FIELD for direct field access
AccessType.PROPERTY for accessing properties using accessors
Maybe it can help you, I already did the same, I put my code, it creates a join table:
#Entity
#Table(name = "custom_pizza")
public class CustomPizza extends BaseEntity {
private static final long serialVersionUID = 1L;
// ManyToMany instead of oneToMany in order to don't have the unique
// constraint on each primary key of the join table
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "custom_pizza_topping", joinColumns = #JoinColumn(name = "custom_pizza_id"), inverseJoinColumns = #JoinColumn(name = "topping_id"))
private Set<Topping> toppings = new HashSet<Topping>();
public void addTopping(Topping topping) {
toppings.add(topping);
}
public void removeTopping(Topping topping) {
toppings.remove(topping);
}
...
And my topping:
#Entity
#Table(name = "topping")
public class Topping extends BaseEntity {
private static final long serialVersionUID = 1L;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "price", nullable = false)
private float price;
....
and the BaseEntity
#MappedSuperclass
public abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
...

How do I join tables on non-primary key columns?

I have an issue with join tables on an object in an ORM class hierarchy where the join column is NOT the primary key of the base class due a lagacy database structure.
Here is an example of the table design:
CREATE TABLE "SCH"."FOO"
(
"OWNERID" NUMBER(10,0) NOT NULL ENABLE,
"FOOID" NUMBER(10,0) NOT NULL ENABLE,
CONSTRAINT "FOO_PK" PRIMARY KEY ("OWNERID", "FOOID")
CONSTRAINT "FOO_FK1" FOREIGN KEY ("OWNERID") REFERENCES "SCH"."OWNERS" ("OWNERID") ENABLE
)
CREATE TABLE "SCH"."BAR"
(
"BARID" NUMBER(10,0) NOT NULL ENABLE,
"FOOID" NUMBER(10,0)
CONSTRAINT "BAR_PK" PRIMARY KEY ("BARID")
)
And here are the mappings (unesessary infomation removed)
#Entity
#IdClass(FooId.class)
#Table(name = "FOO")
public class Foo implements java.io.Serializable
{
#Id
#Column(name = "OWNERID")
private BigInteger ownerId;
#Id
#SequenceGenerator(name = "FOO_GENERATOR", sequenceName = "SEQ_FOO")
#GeneratedValue(generator = "FOO_GENERATOR")
#Column(name = "FOOID")
private BigInteger id;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
#Fetch(value = FetchMode.SUBSELECT)
#Cascade(value = {CascadeType.ALL})
private Set<Bar> bar = new LinkedHashSet<Bar>(0);
}
#Entity
#Table(name = "BAR")
public class Bar implements java.io.Serializable
{
#Id
#Column(name = "BARID")
private BigInteger id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
private Foo foo;
}
This fails with an exception:
Caused by: org.hibernate.AnnotationException: referencedColumnNames(FOOID) of com.package.Bar.foo referencing com.package.Foo not mapped to a single property
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:204)
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:114)
at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1580)
at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1503)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1419)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
Could you please help with a solution?
You must not map the bidirectional association twice. The One side must be marked as the inverse of the Many side, using the mappedBy attribute:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "foo")
#Fetch(value = FetchMode.SUBSELECT)
#Cascade(value = {CascadeType.ALL})
private Set<Bar> bar = new LinkedHashSet<Bar>(0);
...
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "FOOID", referencedColumnName = "FOOID")
private Foo foo;
There is no reason to tell Hibernate twice that the association is mapped by the join column FOOID. And doing it is actually an error, because it defines two different unidirectional associations rather than one bidirectional association.
EDIT
The above should work, but doesn't due to the following Hibernate bug: It's a Hibernate bug. See HHH-4284.
To circumvent this problem, since the FOOID is enough to ensure uniqueness, a solution would be to remove the #Id annotation from the owner ID and the #IdClass annotation.
U can do as follows.... it should work -
#Entity
#IdClass(FooId.class)
#Table(name = "FOO")
public class Foo implements java.io.Serializable
{
#Id
#Column(name = "OWNERID")
private BigInteger ownerId;
#Id
#SequenceGenerator(name = "FOO_GENERATOR", sequenceName = "SEQ_FOO")
#GeneratedValue(generator = "FOO_GENERATOR")
#Column(name = "FOOID")
private BigInteger id;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "FOOID",nullable=false)
#ForeignKey(name = "fk")
private Set<Bar> bar = new LinkedHashSet<Bar>(0);
}
#Entity
#Table(name = "BAR")
public class Bar implements java.io.Serializable
{
#Id
#Column(name = "BARID")
private BigInteger id;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "FOOID", updatable = false, insertable = false, nullable=false)
private Foo foo;
}
You used composite primary key in FOO table. So you should try #EmbeddedId property and you should need two columns "OWNER_ID" and "FOO_ID" in BAR entity that join with FOO entity.

Categories

Resources