I'm using Spring Roo 2.0.0.RC1.
I have a table that has a composite key of two strings. So I defined the PersonId entity :
#RooToString
#Embeddable
#RooSerializable
#RooIdentifier(dbManaged = true)
public class PersonId {
private String postalCode;
#NotNull
private String city;
}
Then I created a Person entity with PersonId as an identifier type :
#RooJavaBean
#RooToString
#RooJpaEntity
#RooEquals(isJpaEntity = true)
public class Person {
#EmbeddedId
private PersonId id;
#Version
private Integer version;
private String address;
#NotNull
private String currentPosition;
}
The project compiles fine, but the problem is that the PersonId's fields don't show on the CRUD form.
How can I make the embedded composite key show in the CRUD form ?
Related
My tables look like this:
School
-------
school_id (pk)
...
Student
school_id (pk) (fk)
student_id (pk)
...
So using JPA (Hibernate), I tried something like this.
#Entity
#Table("SCHOOL")
public School {
#Column(name = "SCHOOL_ID")
private String schoolId;
#OneToMany
private List<Student> students;
}
#Entity
#Table("STUDENT")
public Student {
#EmbeddedId
private StudentPK studentPK;
#ManyToOne
#JoinColumn(name = "SCHOOL_ID")
private School school;
}
#Embeddable
public StudentPK implements Serializable {
#Column(name = "SCHOOL_ID")
private String schoolId;
#Column(name = "STUDENT_ID"
private String studentId;
}
When I do this, I frequently get an error that says that the foreign key constraint is being violated on runtime. I suspect that JPA is trying to generate a new foreign key called "SCHOOL_ID" instead of using the existing column from my composite key, but I'm not sure how to force it to use the existing column.
These relationships should be mapped a bit differently:
#Entity
#Table("SCHOOL")
public School {
#Column(name = "SCHOOL_ID")
private String schoolId;
#OneToMany(mappedBy="school")
private List<Student> students;
}
#Entity
#Table("STUDENT")
public Student {
#EmbeddedId
private StudentPK studentPK;
#ManyToOne
#MapsId("schoolId")
private School school;
}
#Embeddable
public StudentPK implements Serializable {
#Column(name = "SCHOOL_ID")
private String schoolId;
#Column(name = "STUDENT_ID"
private String studentId;
}
Note the #OneToMany.mappedBy attribute on School.students and #MapsId annotation on Student.school.
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
I have a situation with repeatable class fields which I want to mark as #embeddable, however the question is - does JPA allow re-utilizing a class multiple times as embeddable in other different classes?
E.g. my embeddable class looks as follows:
#Embeddable
#Data
public class Audit{
private String name;
private Audit auditor;
private LocalDateTime creationDate;
}
Is it possible to embed the Audit into multiple different classes as for ex.:
#Entity
#Table(name = "BANK")
public class Bank{
#Id
private Long id;
#Column(name = "BANK_NAME")
private String bankName;
#Embedded
private Audit audit;
}
AND
#Entity
#Table(name = "CORPORATION")
public class Corporation{
#Id
private Long id;
#Column(name = "CORPORATION_NAME")
private String corporationName;
#Embedded
private Audit audit;
}
Historically Hibernate called these components. JPA calls them embeddables. Either way, the concept is the same: a composition of values.
Most often, embeddable types are used to group multiple basic type mappings and reuse them across several entities.
Java Code Example:
#Data
#Entity(name = "Book")
public class Book {
#Id
#GeneratedValue
private Long id;
private String title;
private String author;
private Publisher publisher;
}
#Data
#Embeddable
public static class Publisher {
#Column(name = "publisher_name")
private String name;
#Column(name = "publisher_country")
private String country;
}
And this is SQL to show how your table should look like:
create table Book (
id bigint not null,
author varchar(255),
publisher_country varchar(255),
publisher_name varchar(255),
title varchar(255),
primary key (id)
)
More details can be found in the documentation :)
I want to do :
create table user (
id bigint primary key auto_increment,
firstname varchar(128),
lastname varchar(128),
street varchar(128),
zipcode mediumint,
city varchar(128)
)
then :
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstname;
private String lastname;
private Address address; // Here I want an Address rather than street, zip, and city directly inside User
...
}
and :
public class Address {
private String street;
private Integer zipcode;
private String city;
...
}
(that is an example)
How to do that with Hibernate ? #OneToOne ? The problem seems simple and since I can't find the solution around here, it must be obvious.
First, annotate your Address class with #Embeddable:
#Embeddable
public class Address {
/*class definition here*/
...
}
And then update your user class in this way:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstname;
private String lastname;
#Embedded
private Address address;
...
}
That's it. If you want a more complex example look here. Just pay attention to model classes definition, it makes no difference if you are using Spring Boot or not as long as you handle your database with JPA.
You can associate entities through a one-to-one relationship using #OneToOne annotation.
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Address address;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
public Address getAddress()
{
return address;
}
}
Reference:
https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association
I work with mySQL, hibernate and Spring Datas and I want to link a table with more than one entity.
The table looks like this but more complex (with many-to-one relations...) :
CREATE TABLE FOOBAR (
id BIGINTEGER NOT NULL AUTO_INCREMENT,
type ENUM('FOO', 'BAR'),
name VARCHAR(30),
foo_style ENUM('ONE', 'TWO')),
PRIMARY KEY(id);
The entities that I want to create. I want a generic table that cans recover all the entries, and two tables that cans recover only the rows corresponding to the correct enum :
#Table
public class FooBar {
#Id
#Column
private String id;
#Column
#Enumerated(EnumType.STRING)
private Type type;
#Column
private String name;
#Column
#Enumerated(EnumType.STRING)
private FooStyle fooStyle;
}
#Table //On type foo
public class Foo {
#Id
#Column
private String id;
#Column
private String name;
#Column
#Enumerated(EnumType.STRING)
private FooStyle fooStyle;
}
#Table //On type bar
public class Bar {
#Id
#Column
private String id;
#Column
private String name;
}
Thanks in advance !
I am learning Hibernate ORM(v. 3 ) now and I've a got a question.
I have a table called USERS, created with annotations :
package com.hibernatedb.entities;
import javax.persistence.*;
#Entity
#Table(name = "USERS",uniqueConstraints = {#UniqueConstraint(columnNames={"USER_LOGIN", "USER_EMAIL"})})
public class User {
#Column(name = "USER_LOGIN", length=80, nullable=false)
private String login;
#Column(name = "USER_PASS", length=80, nullable=false)
private String password;
#Column(name = "USER_EMAIL", length=80, nullable=false)
private String email;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "USER_ID", nullable=false)
private Long id;
...
// some getters and setters, toString() and other stuff
...
}
And a Product entity :
#Entity
#Table(name = "PRODUCTS",uniqueConstraints = {#UniqueConstraint(columnNames={"PRODUCT_ID", "PRODUCT_NAME"})})
public class Product {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="PRODUCT_ID")
private long id;
#Column(name="PRODUCT_NAME", length=85, nullable=false)
private String name;
#Column(name="PRODUCT_DESCRIPTION", columnDefinition="mediumtext", length=1000)
private String description;
#Column(name="PRODUCT_COST", nullable=false)
private double cost;
So my question is : How can a create a table called like "USER +
User.getId()
BUYS", which contains a 2 foreign keys (USER_ID and PRODUCT_ID) for user in entity (table record) "User" without raw SQL table creation, but using Hibernate annotations or XML mapping.So i want to have something like
public class TransactionEntityBulider() {
public TransactionEntityBulder(User user)
// something that build me "USER + User.getId() BUYS" table and
}
public TransactionEntity getEntity() {
// something that return a "USER + User.getId() BUYS" table entity
}
Also i would like to see some another ways to solve my problem.
I think hibernate is not done for that kind of usage, because you would have to use dynamic mappings. Hibernate provide ways to specify mapping statically (xml and annotations).
I suggest you modify your approach. It normally should not be harmfull to have all the "USER_BUY" in the same table. Example :
#Entity
public class User {
...
#OneToMany(cascade=CascadeType.ALL, mappedBy="user")
List<UserBuys> buys = new ArrayList<UserBuys>();
...
}
#Entity
public class Product { ... }
#Entity
public class UserBuys {
...
#ManyToOne
Product product;
#ManyToOne
User user;
}