So I want to implement a Jpa Repository of my class Reservation.
My RoomType Enum:
public enum RoomType{
BREUGHELZAAL("Breughel zaal"),
CARDIJNZAAL("Cardijn zaal"),
FEESTZAAL("Feest zaal"),
KEUKEN("Keuken"),
RECEPTIEZAAL("Receptie zaal"),
KLEINEKEUKEN("Kleine keuken");
private String roomType;
RoomType(String roomType){
this.roomType= roomType;
}
public String getRoomType(){
return roomType;
}
}
Now I have no clue how to implement this. I need a List of Enum types in my reservation class, i guess it is something like this, but I don't know the annotation for the enum type:
#OneToMany(cascade = CascadeType.ALL)
List<RoomType> chosenRooms
Thanks in advance for the help!!
You don't have sufficient config for Enum persistence, try :
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "RoomType", joinColumns = #JoinColumn(name = "id"))
#Enumerated(EnumType.STRING)
List<RoomType> chosenRooms
#ElementCollection - Defines a collection of instances of a basic type or embeddable class.
#CollectionTable - pecifies the table that is used for the mapping of collections of basic or embeddable types (name - name of the collection table, joinColumn - The foreign key columns of the collection table).
Enumerated - Specifies that a persistent property or field should be persisted as a enumerated type.
Related
I am trying to generate JPA classes for legacy RDMS project.
There is an entity class Person, written in JPA.
The entity Person has another Embeddale class called Address.
I can use set, list or map mapping for Embeddable Address. With any of these there can be multiple embedded objects in Person.
But the requirement is - there can be at most only one instance of embeddable object. How to achieve this requirement? I cannot use subclass entities, it has to be embeddable object only.
You can use single value association something like below
#Entity
public class Person {
#Id
private Long id;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "address_id")
private Address address;
}
#Embeddable
public class Address {
private String street;
private String city;
}
You can read more about #oneToOne here
Using #Embedded annotation the columns of #Embeddable class will be mapped to parent entity's table and hence will have only one instance.
Trying to use specification for filter data at database level.
I have an entity with another entity as an instance wherein the instance variable class contains an Emun field.
This defaults to a string in the database for the enum field.
#Entity
public class Outer{
#OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
#JoinColumn(name = "current_status")
private Status current;
#OneToOne(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
#JoinColumn(name = "past_status")
private Status past;
...
...
#Entity
public class Status{
#Enumerated(EnumType.STRING)
#Column(name = "state")
private State state;
#Id
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid",strategy = "uuid2")
#Column(name = "id")
private String id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "outer_id")
private Outer outer;
I have created static meta models for both the classes.
How do I create a Predicate to match State using a where in clause with the enum values supplied as Strings(not instances of enums) ?
You modeled the entity attribute as an Enum and Hibernate, therefore, expects an enum in all JPQL or Criteria queries.
So, you either have to map all Strings to State enums or use a native SQL query.
Hibernate doesn't parse native queries, and they are based on the table model instead of the entity model. That allows you to use the String representation of your State enum.
You can do something like this:
List<State> states = ... // get or initialize your State list here
Query q = em.createNativeQuery("SELECT * FROM Status s WHERE state IN (:states)", Status.class);
q.setParameter("states", states);
List<Status> s = (List<Status>) q.getResultList();
The second parameter of the createNativeQuery method tells Hibernate to map each record of the result set to a Status entity. These entities are managed, and you can use them to update or remove the mapped database records.
To use this mapping, you need to make sure that your query selects all columns mapped by the entity. I wrote a series of posts that get into more details on the different result mapping options:
Result Set Mapping: The Basics
Result Set Mapping: Complex Mappings
Result Set Mapping: Constructor Result Mappings
Result Set Mapping: Hibernate specific features
There is a foreign key in my entity :
#Entity
#Table(name = "role")
public class Role {
#Id
#Column(name = "role_code")
private String code;
#Column(name = "role_lib")
private String lib;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "role_menu" , joinColumns = {#JoinColumn(name = "role_code")} , inverseJoinColumns = {#JoinColumn(name = "menu_id")} )
#JsonManagedReference
private Set<Menu> menus = new HashSet<Menu>();
// getters and setters
}
It is said in Hibernate documentation that relationship attributes should be of type Interface. Now my problem is when dealing with an instance of this class and using the getMenus() method :
#Override
#Transactional
public Set<Menu> getListMenu(String role_code) {
return ((Role)get(role_code)).getMenus();
}
I want to cast it to a HashSet , but I got castException of persistent object at runtime. So how to make it to be HashSet ?
You cannot cast if the implementations of Set is not HashSet. But you can create a object:
new HashSet(obj.getMenus);
But it's always better to use interfaces, not the implementation.
Here is a note from Hibernate doc:
Hibernate will actually replace the HashSet with an instance of
Hibernate's own implementation of Set. Be aware of the following
errors:
......
(HashSet) cat.getKittens(); // Error!
And here is why you don't actually need to cast nor to create a new object:
The persistent collections injected by Hibernate behave like HashMap,
HashSet, TreeMap, TreeSet or ArrayList, depending on the interface
type.
I'm learning Spring Data JPA and having some trouble establishing the relationship between these two tables:
product table with columns id, name, product_type_id
product_type table with columns id, name
A product can have only one type. A type can be associated with many products.
Where would I use the #OnetoMany and #ManytoOne annotations in my entity classes?
For the situation you mentioned in your question, your entities should be like:
#Entity
public class Product {
#Id
#GeneratedValue
private Long id;
private String name;
#ManyToOne
private ProductType type;
// Getters and setters
}
#Entity
public class ProductType {
#Id
#GeneratedValue
private Long id;
private String name;
#OneToMany(mappedBy = "type")
private List<Product> products;
// Getters and setters
}
Entity Product should have field ProductType with annotation #ManyToOne.
Entity ProductType should have field Set with annotation #OneToMany(mappedBy = 'productType')
Cassio Mazzochi Molin's answer should work for you after correcting the little mistake he made in the inverse entity (I.e. ProductType class). The #OneToMany should be mapped to the variable type in the owning entity (i.e. Product class) and not productType. So that line should be
#OneToMany(mappedBy = "type")
I will also suggest you pick up a good tutorial book on jpa 2 and study, specially the relationship part because there's lot of rules to it which you can only learn by studying on your own else you will keep asking questions here, trust me.
Pro JPA 2 : Mastering the JAVA persistence API by Apress is a very nice tutorial book that can help you.
I am using Hibernate and JPA. If I have two simple entities:
#Entity
#Table(name = "container")
public class Container {
#Id
#Column(name="guid")
private String guid;
}
#Entity
#Table(name="item")
public class Item {
#Id
#Column(name="guid")
private String guid;
#Column(name="container_guid")
private String containerGuid;
}
and I want to insure that inserting an Item fails if the referenced Container does not exist. I would prefer not to have a Container object populated inside the item object (ManyToOne), how would I do this if it is possible to do?
You can declare arbitrary constraint using columnDefinition attribute:
#Column(name="container_guid",
columnDefinition = "VARCHAR(255) REFERENCES container(guid)")
private String containerGuid;
Note, however, that Hibernate doesn't know anything about this constraint, so that, for example, it may not perform inserts in proper order with respect of it and so on.
Therefore it would be better to create a #ManyToOne relationship. If you are afraid of extra SQL query for Container needed to set this property, you can use Session.load()/EntityManager.getReference() to get a proxy without issuing actulal query.
Try using below relationship mapping
RelationShip Mapping
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#ManyToOne()
#ManyToMany()
<>
#JoinColumn(name="<>")