I'm trying to run a simple example which is just a mapping with a table and to print all the values stored in it.
I'm getting all my fields well except my id.
Here is my table when i do an export on it
CREATE TABLE `adress` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`streetNumber` tinyint(4) DEFAULT NULL,
`street` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`zipCode` int(11) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
LOCK TABLES `adress` WRITE;
INSERT INTO `adress` VALUES (1,12,'Canada street','LOS ANGELES',441233,'California'),(2,54,'5th avenue','NEW YORK CITY',884769,'New York');
UNLOCK TABLES;
My Entity class :
#Entity
#Table(name = "adress")
#XmlRootElement
public class Adress implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "streetNumber")
private Short streetNumber;
...
If i do a "findAll()" i'm able to get all my datas from the db.
But the id is null, all the other fields have their values
I have tried several stuff but i'm not going everywhere.
If someone can see where or about what is my mistake i'll appreciate a lot your help.
Thanks in advance
Related
I'm new to JPA and trying to understand if there's a way to make an Entity where one column is coming from another table that is linked by a foreign key. For example, consider the following tables:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `jobs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11),
PRIMARY KEY (`id`),
CONSTRAINT `fk_jobs_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
);
Now I want to make an Entity for the "jobs" table that will include the user.email. I know I can do something like
#Entity
#Table(name = "jobs")
public class JobEntity {
#Id
#Column(name = "id")
private Long id;
#Column(name = "user_id")
private Long userId;
#Formula("(select user.email FROM user WHERE user.id = user_id)")
private String userEmail;
But I feel there's a way I can better leverage the foreign key relationship, but I'm not sure how. I was looking into #JoinColumn but was not seeing the result I wanted since the foreign key is a different column in my Entity. Is there a better way rather than using #Forula to do this?
I don't really understand this. I'm sure #JoinColumn can accomplish the behavior you're looking for.
I was looking into #JoinColumn but was not seeing the result I wanted since the foreign key is a different column in my Entity
Example:
#Entity
#Table(name = "jobs")
public class KronosFileEntity {
#Id
#Column(name = "id")
private Long id;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumn = "id")
private User user;
}
Then you can access the email like job.getUser().getEmail()
Or add a convenience method if that helps
public String getUserEmail() {
return user.getEmail();
}
Then
job.getUserEmail()
In my db I have two tables which look like this:
CREATE TABLE IF NOT EXISTS `Lokal` (
`idLokal` int(11) NOT NULL AUTO_INCREMENT,
`Ocena_idOcena` int(11) NOT NULL,
PRIMARY KEY (`idLokal`,`Ocena_idOcena`),
KEY `fk_Lokal_Ocena_idx` (`Ocena_idOcena`)
)
CREATE TABLE IF NOT EXISTS `Ocena` (
`idOcena` int(11) NOT NULL AUTO_INCREMENT,
`Ocena` int(1) DEFAULT NULL,
PRIMARY KEY (`idOcena`)
)
I want to map my Lokal entity to this Ocena table using #SecondaryTable Hibernate annotation, what I managed to achieve is this:
#Entity
#Table(name="Lokal")
#SecondaryTable(name = "Ocena", pkJoinColumns=#PrimaryKeyJoinColumn(name="Ocena_idOcena"))
public class Lokal {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="idLokal")
private int id;
#Column(table="Ocena" ,name="idOcena")
private int rating;
//--Getters and Setters skipped--//
}
But all I get is an error saying:
ERROR: Unknown column 'this_1_.Ocena_idOcena' in 'on clause'
I think I'm misunderstanding the #SecondaryTable annotation, but this is my first Spring/Hibernate application so I'd be glad for any kind of help.
Try this:
#Entity
#Table(name="Lokal")
#SecondaryTable(name = "Ocena", pkJoinColumns=#PrimaryKeyJoinColumn(name="idOcena"))
public class Lokal {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="idLokal")
private int id;
#Column(table="Ocena" ,name="rating")
private int rating;
//--Getters and Setters skipped--//
}
I am using MySQL with Hibernate and JPA2.
I have the following table, which I would expect to auto generate the ID because AI (Auto Increment) is checked:
CREATE TABLE `job` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`JOINING_DATE` double NOT NULL,
`LASTACCESS_DATE` double NOT NULL,
`PHONE_NUMBER` varchar(55) DEFAULT NULL,
`MOBILE_NUMBER` varchar(55) DEFAULT NULL,
`EMAIL_ADDRESS` varchar(55) DEFAULT NULL,
`SEX` int(1) DEFAULT NULL,
`JOB_TITLE` varchar(65) NOT NULL,
`JOB_DESCRIPTION` varchar(800) NOT NULL,
`JOB_DETAILS` varchar(800) DEFAULT NULL,
`DRIVERS_LICENCE` int(1) DEFAULT NULL,
`AVATAR` longblob,
`TYPE` int(1) NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID_UNIQUE` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=87 DEFAULT CHARSET=utf8;
Job.java
#Entity
#Table(name = "job")
#XmlRootElement(name = "job")
public class Job extends AbstractDomain<Long> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
Dao.java
protected T merge(T entity) throws InstantiationException, IllegalAccessException {
T attached = null;
if (entity.getId() != null) {
attached = entityManager.find(entityClass, entity.getId());
}
if (attached == null) {
attached = entityClass.newInstance(); // <= this is executed
}
BeanUtils.copyProperties(entity, attached);
entityManager.merge(attached); // <= ID is null here
return attached;
}
When I try merge the table, I get the following error:
Caused by: java.sql.SQLException: Field 'ID' doesn't have a default value
Strange thing is this was working earlier, and the Java code has not changed, I did make changes to some other database tables only. I have read here that some people had this problem and fixed it by dropping and importing their database. I did drop the schema and imported it again. But still get the same error.
Does anyone have any ideas please?
In a spring mvc app using hibernate over MySQL, I am encountering problems when I try to create polymorphic subclasses that inherit their id from a BaseEntity. You can see my intended use when you read my AccessLog class below, which has properties of type BaseEntity. The actor_entity and target_entity properties should each be fillable with a variety of different types of entities, such as User, OutsideSystem, Document, etc., each of which inherit from BaseEntity.
How do I set this up in code?
Here is my current java:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
protected Integer id;
//other stuff
}
#Entity
#Table(name="users")
public class User extends BaseEntity{
//other stuff
}
#Entity
#Table(name = "accesslogs")
public class AccessLog extends BaseEntity{
#ManyToOne
#JoinColumn(name = "actorentity_id")
private BaseEntity actor_entity;
#ManyToOne
#JoinColumn(name = "targetentity_id")
private BaseEntity target_entity;
#Column(name="action_code")
private String action;
}
Here is my current DDL:
CREATE TABLE IF NOT EXISTS baseentity(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS accesslogs(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
actorentity_id int(11) UNSIGNED NOT NULL,
targetentity_id int(11) UNSIGNED NOT NULL,
action_code varchar(100),
access_date DATETIME
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE roles (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
role varchar(20) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE users (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
login varchar(20) NOT NULL,
password varchar(20) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE user_roles (
user_id int(11) UNSIGNED NOT NULL,
role_id int(11) UNSIGNED NOT NULL,
KEY user (user_id),
KEY role (role_id)
) ENGINE=InnoDB;
Why do you need BaseEntity annotate with Entity? You don't need to specify #Inheritance(strategy = InheritanceType.JOINED). BaseEntity should have #MappedSuperclass annotation
And you don't need to create baseentity table
I'm trying to find relevant JPA documentation, but having trouble finding anything that specifies if I am allowed to make an ElementCollection of an Entity. I know the typical use is to make an #ElementCollection of #Embeddable, but due to a Hibernate bug I encountered, I need to make my embeddable class into its own entity.
I would like to maintain the entity's lifecycle to be controlled by the parent class. Consequently, I am hoping not to create any DAO/Repository for the new entity.
Although Hibernate allows this to occur (it properly generates the DDL), I have not actually tested persistence of the parent entity yet.
Additionally, I have not been able to find any way to specify the join column mapping to the new entity.
For example, given:
public class User {
#TableGenerator( name="UUIDGenerator", pkColumnValue="user_id", table="uuid_generator", allocationSize=1)
#Id
#GeneratedValue(strategy = GenerationType.TABLE, generator="UUIDGenerator")
#Column(name = "id")
private Long id;
/**
* Address
*/
#Valid
#ElementCollection(fetch=FetchType.LAZY)
#CollectionTable(name="user_address", joinColumns=#JoinColumn(name = "user_id", referencedColumnName = "id"))
#OrderColumn
private List<Address> address;
}
and
#Entity
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
/**
* Multiple street lines allowable
*/
#NotBlank
#ElementCollection(targetClass=String.class, fetch=FetchType.LAZY)
#CollectionTable( joinColumns=#JoinColumn(name = "address_id", referencedColumnName = "id"))
#OrderColumn
private List<String> street;
}
it generates the following MySQL tables:
CREATE TABLE `user` (
`id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_address` (
`user_id` bigint(20) NOT NULL,
`address` bigint(20) NOT NULL,
`address_order` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`address_order`),
UNIQUE KEY `UK_m09f5sbmw3q9drll2qig9i07q` (`address`),
KEY `FK_m09f5sbmw3q9drll2qig9i07q` (`address`),
KEY `FK_kfu0161nvirkey6fwd6orucv7` (`user_id`),
CONSTRAINT `FK_kfu0161nvirkey6fwd6orucv7` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
CONSTRAINT `FK_m09f5sbmw3q9drll2qig9i07q` FOREIGN KEY (`address`) REFERENCES `address` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address_street` (
`address_id` bigint(20) NOT NULL,
`street` varchar(255) DEFAULT NULL,
`street_order` int(11) NOT NULL,
PRIMARY KEY (`address_id`,`street_order`),
KEY `FK_jrcnrclixxqroefuqc7gjhoh` (`address_id`),
CONSTRAINT `FK_jrcnrclixxqroefuqc7gjhoh` FOREIGN KEY (`address_id`) REFERENCES `address` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I'd like to find a way to change the field name for user_address.address. So far, the only way I can figure out how to do this is to make it a #OneToMany mapping and use a #JoinTable() definition. Is there no way from within #ElementCollection?
You cannot have an ElementCollection containing Entities, these are mutually exclusive concepts in JPA.
You can try a one-to-many or many-to-many depending on your needs. If you set fetching to eager and cascade all it should be fine.