No Primary key error when i put ManyToOne annotation - java

I have this hierarchy
T1(
id (pk),
name (varchar)
)
T2(
id (pk),
t1_id (fk_t1),
number (int)
)
T3 (
id (pk),
t2_id (fk_t2),
time (datetime)
zone (tinyint),
name (varchar)
)
and this is my T3Entity
#Entity
#Table(name="T3, schema="", catalog="dbname")
public class T3Entity{
private int id;
private DateTime datetime;
private int zone;
private String name;
#Id
#Column(name="id", nullable=false, insertable=true, updatable=true)
//GETTER/SETTERS
#Basic
#Column(name="datetime", nullable=false, insertable=true, updatable=true)
//GETTER/SETTERS
#Basic
#Column(name="zone", nullable=false, insertable=true, updatable=true)
//GETTER/SETTERS
#Basic
#Column(name="name", nullable=false, insertable=true, updatable=true)
//GETTER/SETTERS
}
When I added this code in T3Entity class, I got an error
#ManyToOne(fetch=FetchType.Lazy)
#JoinColumn(name="T2_id", referencedColumn="T2_id")
private T2Entity t2Entity;
//getters-setters
I got this error
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [PU] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.project.entity.T3Entity] has no primary key specified. It should define either an #Id, #EmbeddedId or an #IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.

Shouldn't this be
#JoinColumn(name="T2_id")
instead of
#JoinColumn(name="T2_id", referencedColumn="T2_id")
I don't know about EclipseLink, but Hibernate won't even let me specify a non-existant column name as the referencedColumn. If you insist, it should be
#JoinColumn(name="T2_id", referencedColumn="id")
so that it references a column that exists.

Related

EclipseLink: #Enumerated is not taken into account on inherited fields from a parent Entity

Using WildFly Full 17.0.1.Final (WildFly Core 9.0.2.Final) / EclipseLink 2.7.7 with MySQL server, I have few fields (of enum type, of Instant as well) in a parent entity (#MappedSuperclass) that I want to inherit in few sub-entities.
The problem I have is that the annotation #Enumerated(STRING), put in the parent entity fields, is not taken into account and EclipseLink is trying to persist the enums as integers instead of as strings.
The same issue with Instant type fields - the annotation #Convert(converter = InstantConverter.class) is not taken into account
When I move the fields to live in the child entities (not using inheritance), it works as expected.
Here is the code:
#MappedSuperclass
#Access(AccessType.PROPERTY)
public abstract class BaseEntity {
#Id
#Column(name = "ID", nullable = false)
private String id;
#Column(name = "STATUS", nullable = false)
#Enumerated(EnumType.STRING)
private StatusEnum status;
#Column(name = "TIMESTAMP", nullable = false)
#Convert(converter = InstantConverter.class)
private Instant timestamp;
// ... getters, setters
}
#Entity
#Table(name = "child1")
public class ChildEntity extends BaseEntity {
// other fields with getters and setters
}
The exceptions:
[EL Warning]: UnitOfWork(353321401)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '\xAC\xED\x00\x05sr\x00\x0Djava.time.Ser\x95]\x84\xBA\x1B"H\xB2\x0C\x00\x00xpw\x0D\x02\x00\x00\x00\x00aI\xD3\x86\x1B\xDD\xBCTx' for column 'TIMESTAMP' at row 1
[EL Warning]: UnitOfWork(597716366)--Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [FAILURE], of class [class java.lang.String], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[status-->d.s.STATUS]] with descriptor [RelationalDescriptor(d.e.ChildEntity --> [DatabaseTable(...)])], could not be converted to [class java.lang.Integer].
Internal Exception: java.lang.NumberFormatException: For input string: "FAILURE"
Any idea how to resolve this problem?
Edit: There is no #Entity annotation on BaseEntity class as it is #MappedSuperclass. There is no table in DB behind it as well and this is the desired model. I just mention it, don't know if it is related to the issue.

MappingException with Unknown entity and #Generated Annotation

I want to set a default value for my forein key status_id.
So I created a trigger inside Oracle, which sets a default value on insert. After that, Hibernate should update the linked foreign instance.
I have following Database in Oracle:
CREATE TABLE status (
status_id NUMBER(10) NOT NULL,
name VARCHAR2(50) NOT NULL,
CONSTRAINT status_pk PRIMARY KEY (status_id)
);
CREATE TABLE customer (
customer_id NUMBER(10) NOT NULL,
street VARCHAR2(50),
zip VARCHAR2(50),
city VARCHAR2(50),
salutation VARCHAR2(50),
title VARCHAR2(50),
firstname VARCHAR2(50),
surname VARCHAR2(50),
phone VARCHAR2(50),
fax VARCHAR2(50),
email VARCHAR2(50),
type VARCHAR2(50),
status_id NUMBER(10) NOT NULL,
CONSTRAINT customer_pk PRIMARY KEY (customer_id),
CONSTRAINT customer_status_fk FOREIGN KEY (status_id) REFERENCES status(status_id)
);
INSERT INTO status (status_id, name) VALUES ('1', 'DEFAULT');
INSERT INTO status (status_id, name) VALUES ('2', 'PREMIUM');
INSERT INTO status (status_id, name) VALUES ('3', 'SUPPLIER');
I want to set status to 'DEFAULT' if not specified when inserting a new customer. So I created following Trigger:
CREATE OR REPLACE TRIGGER status_default_trigger BEFORE INSERT ON customer FOR EACH ROW BEGIN
IF :NEW.type IS NULL THEN
SELECT 'NEW' INTO :NEW.type FROM DUAL;
END IF;
IF :NEW.status_id IS NULL THEN
SELECT status_id INTO :NEW.status_id FROM status WHERE status.status_id = 1;
END IF;
END;
/
My Entities looks as follows:
Status.java:
#Data
#Entity
#Table(name = "status")
public class Status {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private BigDecimal statusId;
#OneToMany(mappedBy = "status", fetch = FetchType.LAZY)
private List<Customer> customerList;
#Column
private String name;
}
Customer.java:
#Data
#Entity(name = "einsender")
#Table(name = "einsender")
public class Einsender {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private BigDecimal einsenderId;
#Generated(GenerationTime.INSERT) // This fails to start Hibernate entityManager
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "status_id")
private Status status;
#Column
private String street;
#Column
private String zip;
#Column
private String city;
#Column
private String salutation;
#Column
private String title;
#Column
private String firstname;
#Column
private String surname;
#Column
private String phone;
#Column
private String fax;
#Column
private String email;
#Generated(GenerationTime.INSERT) // This works instead
#Column
private String type;
}
I expect that Customer.Status will be default Status(statusId=1,name='DEFAULT); But I get following Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Unknown entity: de.example.model.Status
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
...
Caused by: org.hibernate.MappingException: Unknown entity: de.bund.bamf.vup.service.vorgang.model.Status
By the fact, the Customer.type Value will be mapped if I comment #Generated(GenerationTime.INSERT) above private Status status;

Hibernate #Enumerated seems to be ignored

I have the class Person mapped with annotations with enum Sex reffering to the sex if is male or female. Let's see:
#Entity
#Table(name = "PERSON")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Enumerated(EnumType.STRING)
#Column(name = "SEX")
private Sex sex;
private enum Sex {
M,
F;
}
// Getters, setters & constructors
}
When I test getting all the rows from the MySQL database, it works and the mapping is correct.
The database is already predefined, here is the column's definition:
`SEX` enum('M','F') NOT NULL
However the error occurs when I configure Hibernate with hibernate.hbm2ddl.auto=validate:
found [enum (Types#CHAR)], but expecting [varchar(255) (Types#VARCHAR)]
The error is a bit different (expecting [integer (Types#INTEGER)]) happend when I use EnumType.ORDINAL or no #Enumerated at all.
What do I do wrong?
try add columnDefinition
#Enumerated(EnumType.STRING)
#Column(name = "SEX" , columnDefinition="ENUM('M','S')" ,nullable = false )
private Sex sex;
hibernate validate do check types , lenght.... as you have this in db level validator thinks it's different type .
I didn't see it with Oracle , but with MySql it's might be

hibernate.MappingException When Saving POJO in Hibernate Table

UserDO.java
#Entity
#Table(name = "UserDO")
public class UserDO {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
private boolean successfullyLinked;
private UserInformation userInformation;
}
UserInformation.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "address", "country_code", "currency_code", "email_address", "name", "phone" })
public class UserInformation {
#JsonProperty("address")
#Valid
private Address address;
#JsonProperty("country_code")
#NotNull
private String countryCode;
#JsonProperty("currency_code")
#Size(min = 3, max = 3)
private String currencyCode;
#JsonProperty("email_address")
#NotNull
private String emailAddress;
#JsonProperty("name")
#Valid
#NotNull
private Name name;
#JsonProperty("phone")
#Valid
private Phone phone;
}
I am trying to save the UserInformation POJO as a part of the UserDO in Hibernate. However upon running this as part of a Spring Boot Application, I get an error. The following is the stack trace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
Caused by: org.hibernate.MappingException: Could not determine type for: com.paypal.marketplaces.vaas.api.models.UserInformation, at table: Tracking, for columns: [org.hibernate.mapping.Column(userInformation)]
Note: The UserInformation POJO is quite complex, with other objects inside it and objects inside those objects (and so on). Any solution not requiring explicit mapping of the UserInformation POJO to colums of the UserDO table would be preferable.
Any help would be highly appreciated!
Persistence provider is not aware of that class, neither what to do with it.
I would suggest making it Embeddable and optionally specifying column names:
import javax.persistence.Embeddalbe;
import javax.persistence.Column;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "address", "country_code", "currency_code", "email_address", "name", "phone" })
#Embeddable
public class UserInformation {
#JsonProperty("country_code")
#NotNull
#Column(name = "COUNTRY_CODE")
private String countryCode;
You would have to repeat the process for every nested class.
And finally to annotate the userInformation with:
#Embedded
private UserInformation userInformation;

Modeling Table Relationships using JPA in Java EE

I have two 3 tables in my database:
group
----------
groupId PK
name
user_account
----------
userId PK
user_grouping
----------
groupId PK FK grouping(groupId -> groupId)
userId PK FK user_account(userId -> userId)
In my UserAccount Entity, I have the following line:
#JoinTable(name = "user_group", joinColumns = {
#JoinColumn(name = "userId", referencedColumnName = "userId")}, inverseJoinColumns = {
#JoinColumn(name = "groupId", referencedColumnName = "groupId")})
#ManyToMany
private List<Grouping> groupingList;
This is to show the relationship between all the tables. However, when I deploy, I get the following error:
SEVERE: Exception while preparing the app : Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.dv_model_ejb_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field groupingList] from the entity class [class com.dv.model.entity.UserAccount] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
Local Exception Stack:
Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [com.dv_model_ejb_1.0-SNAPSHOTPU] failed.
Internal Exception: Exception [EclipseLink-7220] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The #JoinColumns on the annotated element [field groupingList] from the entity class [class com.dv.model.entity.UserAccount] is incomplete. When the source entity class uses a composite primary key, a #JoinColumn must be specified for each join column using the #JoinColumns. Both the name and the referencedColumnName elements must be specified in each such #JoinColumn.
at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:221)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1402)
...
I am not sure exactly how to interpret this error message. I am assuming I do not have the table relationship correctly modeled in my entity. But I am not sure why. Before today, this was compiling fine. Can anyone provide assistance?
Description of tables is inconsistent (grouping vs group) and name of join table in entity mappings is not one of the table names. Because of these
inconsistencies I assume following table structure:
useraccount (userid PK)
grouping (groupdid PK, name)
user_grouping (userId PK, groupId PK)
- FK userId references to user_account.userid
- FK groupId references to grouping.groupId
One correct way to map this to two entities is following:
#Entity
public class UserAccount {
#Id int userId;
#JoinTable(name = "user_grouping", joinColumns = {
#JoinColumn(name = "userId", referencedColumnName = "userId")},
inverseJoinColumns = {
#JoinColumn(name = "groupId", referencedColumnName = "groupId")})
#ManyToMany
private List<Grouping> groupingList;
//get and set omitted.
}
#Entity
public class Grouping {
#Id int groupId;
String name;
//get,set, and optional inverse side of relationship omitted
}

Categories

Resources