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--//
}
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()
I use Hibernate to control my database and I have 2 tables:
CREATE TABLE IF NOT EXISTS `User`(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '',
`account` VARCHAR(255) NOT NULL DEFAULT '',
`password` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
)
CREATE TABLE IF NOT EXISTS `Project` (
`id` INT NOT NULL AUTO_INCREMENT,
`manager` INT NOT NULL,
`name` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
FOREIGN KEY (`manager`) REFERENCES `User`(`id`)
)
And I have done the mapping:
User:
// ... import code
#Entity
#Table
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column
private String name, account, password;
#OneToMany(mappedBy = "manager")
private List<Project> projects;
public User() {
}
// ... Getter & Setter code
}
Project:
// ... import code
#Entity
#Table
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column
private String name;
#ManyToOne
#JoinColumn(name = "manager")
private User manager;
public Project () {
}
// ... Getter & Setter code
}
I want to know whether it is possible when I select projects, the project will include its manager data but not have password.
In other ways, I want that each project I get will like this (format as JSON):
{
"id": 0,
"name": "A test project",
"manager": {
"id": 0,
"name": "John Smith"
"accound": "user1",
"password": null
}
}
1. Projection
A projection could be used to limit the fields you want to bring into memory, you could get a projection of all fields except the password.
2. Lazy
Another option can be adding the lazy annotation to the field:
#Basic(fetch = FetchType.LAZY)
#Column(...)
private String password;
3. HQL query
Another way would be to use a direct HQL query and load only the required fields, from this answer.
If you don't want to map this field at all, you could use #Transient annotation:
#Transient
private String password;
If you simply don't want to show this field when you convert the object to a particular JSON representation, then this is a data representation problem, not a ORM mapping problem. You should skip this field when you convert your object to JSON. The implementation depends on what JSON converter you are using. For instance, if you use Jackson, then the #JsonIgnore annotation is what you need.
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 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
I've created the following scenario:
#javax.persistence.Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class MyEntity implements Serializable{
#Id
#GeneratedValue
protected Long id;
...
#ElementCollection
#CollectionTable(name="ENTITY_PARAMS")
#MapKeyColumn (name = "ENTITY_KEY")
#Column(name = "ENTITY_VALUE")
protected Map<String, String> parameters;
...
}
As well as:
#javax.persistence.Entity
public class Sensor extends MyEntity{
#Id
#GeneratedValue
protected Long id;
...
// so here "protected Map<String, String> parameters;" is inherited !!!!
...
}
So running this example, no tables are created and i get the following message:
WARNUNG: Got SQLException executing statement "CREATE TABLE ENTITY_PARAMS (Entity_ID BIGINT NOT NULL, ENTITY_VALUE VARCHAR(255), ENTITY_KEY VARCHAR(255), Sensor_ID BIGINT NOT NULL, ENTITY_VALUE VARCHAR(255))": com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Duplicate column name 'ENTITY_VALUE'
I also tried overriding the attributes on the Sensor class...
#AttributeOverrides({
#AttributeOverride(name = "ENTITY_KEY", column = #Column(name = "SENSOR_KEY")),
#AttributeOverride(name = "ENTITY_VALUE", column = #Column(name = "SENSOR_VALUE"))
})
... but the same error.
EDIT:
Okay, I'd found out that with the Inheritance strategy "JOINED" as well as with "SINGLE_TABLE" everything works fine.
Also it seems that it has nothing to do with the EclipseLink version - I tried 1.3 and 2.0.1.
END_EDIT
Can anybody help me?
Okay, I've just found out what was wrong!
In such a scenario I'd built you should couldn't use the #CollectionTable(name="ENTITY_PARAMS") annotation.
So, by just using...
#ElementCollection
#MapKeyColumn (name = "PARAM_KEY")
#Column(name = "PARAM_VALUE")
private Map parameters;
Every works fine, and the resulting tables (in MySQL) are:
CREATE TABLE Sensor_PARAMETERS (
Sensor_ID BIGINT NOT NULL,
PARAM_VALUE VARCHAR(255),
PARAM_KEY VARCHAR(255)
)
and
CREATE TABLE Entity_PARAMETERS (
Entity_ID BIGINT NOT NULL,
PARAM_VALUE VARCHAR(255),
PARAM_KEY VARCHAR(255)
)
So, without that attribute everything works fine....
Hope, nobody needs this post. Even if: "Congratulation, you found the answer!" ;-)