I'm in need of help with hibernate annotation, when I have a table with same parent id.
Like this example
CREATE TABLE `server` (
`server` int(11) DEFAULT NULL,
`name` varchar(20) DEFAULT NULL,
`parentid` int(11) DEFAULT NULL,
KEY `parentid` (`parentid`),
KEY `server` (`server`),
CONSTRAINT `server_fk` FOREIGN KEY (`parentid`) REFERENCES `server` (`server`)
);
Output like this
Server A
Server B
Server C
Server D
Server E
Server C
Server D
Server F
Server G
How can I map this in my Class
#Entity
public class Server {
#Id #GeneratedValue
private Long id;
private String name, description;
private Server parentid;
}
Related
I am working on a school project, and I am having trouble with joining tables so I can display output in JSP file using JSTL. I will provide all necessary code. I know that I need to connect entities somehow, but I don't know how.
SQL:
CREATE TABLE IF NOT EXISTS `totelegram`.`contacts` (
`id` INT NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL,
`last_name` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL,
`phone_number` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
UNIQUE INDEX `phone_number_UNIQUE` (`phone_number` ASC))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `totelegram`.`messages` (
`id_message` INT NOT NULL AUTO_INCREMENT,
`message` VARCHAR(2000) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT
NULL,
`time` VARCHAR(45) NOT NULL,
`contacts_id` INT NOT NULL,
PRIMARY KEY (`id_message`),
UNIQUE INDEX `id_message_UNIQUE` (`id_message` ASC),
INDEX `fk_messages_contacts_idx` (`contacts_id` ASC),
CONSTRAINT `fk_messages_contacts`
FOREIGN KEY (`contacts_id`)
REFERENCES `totelegram`.`contacts` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Contacts.java
#Entity(name = "contacts")
public class Contacts implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#javax.persistence.Column(name = "first_name")
private String firstName;
#javax.persistence.Column(name = "last_name")
private String lastName;
#javax.persistence.Column(name = "phone_number")
private String phoneNumber;
...getters/setters, constructor, toString...
Messages.java
#Entity(name = "messages")
public class Messages implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#javax.persistence.Column(name = "id_message")
private int id;
private String message;
private String time;
#javax.persistence.Column(name = "contacts_id")
private int contactsId;
...getters/setters, constructor, toString...
MessagesRepository.java
public interface MessagesRepository extends JpaRepository<Messages, Integer> {
//custom query which will output this
//SELECT b.message, b.time, b.contacts_id, a.first_name, a.last_name FROM messages AS b INNER JOIN contacts as A ON (b.contacts_id=a.id) ORDER BY time ASC;
public List<Messages> findAll();
}
I hope I was clear. Thanks to everybody in advance.
As far as i understand, one contact can have N messages and you cannot have a Message without the Contact, right?
Since you have relations between classes, you have to use specific annotations in jpa, for example:
in the Message Class, you should use the #ManyToOne annotation, since you have Many Messages for One Contact. The JoinColumn will input the contacts_id in the Messages Table.
#ManyToOne
#JoinColumn(name = "contacts_id")
private Contacts contact;
in the Contacts Class, you should use #OneToMany annotation, since One Contact has Many Messages. The mappedBy makes a reference in contact at the Message Class.
#OneToMany(mappedBy = "contact")
private List<Messages> messages = new ArrayList<>();
So far you made a Bidirectional reference between Contacts and Messages. Now in your service class, i would recommend you find the Messages through the Contacts, since you cannot have a message without the contact. Its a Repository principle.
Contacts con = repository.findOne(1);
con.getMessages();
btw, sorry for the bad english.
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--//
}
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.
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