One to One Mapping in Hibernate Unidirectional with MySQL DB? - java

Am new to Hibernate and MySQL, i have two Table like OFFER_TABLE and OFFER_LIKES_DISLIKES
OFFER_TABLE Columns
OFR_ID(PK)
OFR_MSG
OFFER_LIKES_DISLIKES Columns
OFFER_LIKES_DISLIKES_ID
OFR_ID(FK)
LIKE
DISLIKE
I want to map OFFER_TABLE and OFFER_LIKES_DISLIKES, Access the OFFER_LIKES_DISLIKES data through OFFER_TABLE. Am using One to One Mapping but its not Working.
Hibernate Annotation Mapping Java Class
Offers.class
#Id
#GeneratedValue
#Column(name = "OFR_ID", length = 11, nullable = false)
private int offer_id;
#OneToOne
#JoinColumn(name="OFR_ID", unique = true)
#OneToOne(cascade = CascadeType.ALL)
private MessageLikeDislikesDAO likeDislikes;
LikeDislike.class
#GeneratedValue
#Column(name="LIKES_DISLIKES_ID", length = 11, nullable = false)
private int likes_dislikes_id;
#Expose
#Column(name="OFR_ID", length = 11, nullable = false)
private int offer_id;
When I get the Data of Offers, want Like and Dislike data associated with it. In LikeDislike table OFR_ID is UNIQUE. Am used One to One. But i didn't get the data of LikeDislike. Which one is best way to took that data. Help me to solve this issue.

There are many problems:
You're creating an association with a DAO instead of creating an association with an entity
You're storing the ID of the offer in the LikeDislike entity instead of storing an association with the Offer entity
You're saying that there is a join column named OFR_ID and referring to the LikeDislike entity in the OFFER table.
You disrespect Java naming conventions
You're setting two OneToOne annotations on the same field
The mapping should be:
Offer:
#Id
#GeneratedValue
#Column(name = "OFR_ID", length = 11, nullable = false)
private Integer offerId;
#OneToOne(mappedBy = "offer", cascade = CascadeType.ALL)
private LikeDislike likeDislike;
LikeDislike:
#GeneratedValue
#Column(name="LIKES_DISLIKES_ID", length = 11, nullable = false)
private Integer likeDislikeId;
#Expose
#OneToOne
#JoinColumn(name="OFR_ID", length = 11, nullable = false)
private Offer offer;
Relevant documentation

Related

Possible to retrieve selected children list from database only by using JPA/Hibernate-Annotation?

Guess this might be a difficult one. Well, at least for me. I need some help with JPA/Hibernate-Annotations and I was wondering, if there is a way to solve my problem. Unfortunately, my own skills seem too limited to solve that problem by myself. That's why I'm hoping to find anyone here who might have a good grasp on jpa-annotations and relational databases (here: oracle).
Task:
I have three tables (see attached image! Please don't change this part, since the tables aren't supposed to be created! They already exist with exactly these names, may not be changed and the primary key + foreign key part is just to provide more information about these already existing tables that I uploaded here as an image! Thank you.):
CONSTANT (PRIMARY KEY CONSTANT(ID) + FOREIGN KEY (PARENT_CONSTANT_ID) REFERENCES CONSTANT(ID)),
COUNTRY (PRIMARY KEY COUNTRY(ID)),
COUNTRY_TO_CONSTANT (PRIMARY KEY COUNTRY_TO_CONSTANT(COUNTRY_ID, CONSTANT_ID))
as shown here: Tables-Image
Java-Beans look like that:
Constant.java
#Id
#Column(name = "ID")
private Integer id;
#Basic
#Column(name = "CODE")
private String code;
#Basic
#Column(name = "SORT_KEY")
private int sortKey;
#ManyToOne
#JoinColumn(name = "CONSTANT_TYPE_ID", referencedColumnName = "ID")
private ConstantType constantType;
#ManyToOne
#JoinColumn(name = "parent_constant_id", referencedColumnName = "ID")
private Constant parent;
#OneToMany(mappedBy = "parent", targetEntity = Constant.class)
private List children;
...
public Collection<Constant> getChildren() {
return children;
}
CountryToConstant.java
#Id
#Basic
#Column( name = "COUNTRY_ID" )
private Integer countryID;
#Id
#Basic
#Column( name = "CONSTANT_ID" )
private Integer constantID;
Country.java
#Id
#Column( name = "ID" )
#SequenceGenerator( name = "CountrySequence", sequenceName = "COUNTRY_ID_SEQ" )
#GeneratedValue( generator = "CountrySequence" )
private Integer id;
#Basic
#Column( name = "CODE" )
private String code;
#Basic
#Column( name = "NAME" )
private String name;
#Basic
#Column( name = "LANGUAGE_CODES" )
private String languageCodes;
I left out all getters + setters for brevity except for the constant.java-getter of the 'children'-attribute, since this is the only getter needed for this issue. To make it more difficult: The structure of the java-beans shown above may not be changed, but is allowed to be expanded. This is due to not destroying the already existing (very complex) programm structure.
private List children (Constant.java) is mapped by the attribute private Constant parent. Let's assume that by the other program logic a list with 'parent' CONSTANT ids (e.g. id = {11, 12}) is used here to iterate through and handed over one after another to create 1 parent-object. As a result this will create one private List children after another. Therefore, the result of the example would be 2 separate children lists due to the iteration:
parent-id 11 -> children-id-list: {111, 112, 113, 114, 115, 116}
id 12 -> id-list: {121, 122, 123}) for each parent-object.
What I need to get instead is a specific list corresponding to the COUNTRY_TO_CONSTANT table, only by using annotations. For example: If the person uses a browser in Germany, the locale is set to de_DE resulting in the COUNTRY.id '1001'. And based (only) on the country code (not the locale), the result for the iteration example above (CONSTANT.id = {11, 12}) should be these two lists:
parent-id 11 -> children-id-list: {111, 112, 113} (leaving out constant-id 114, 115, and 116)
parent-id 12 -> children-id-list: {121} (leaving out constant-id 122, and 123)
Idea is that depending on the country code and the CONSTANT.IDs put in the table COUNTRY_TO_CONSTANT, every list is created individually corresponding to the related database entries.
Since private List children cannot be changed in definition, what I need is a second attribute (e.g. private List children2) that works exactly like private List children with the only difference that only the country related children (see COUNTRY_TO_CONSTANT table) should be mapped by private Constant parent.
I was thinking about something like:
#OneToMany(mappedBy = "parent", targetEntity = Constant.class)
//Any annotation to get what I need.
private List children2
or maybe:
#ManyToMany(mappedBy = "children", targetEntity = Constant.class)
//Any annotation to get what I need.
private Set children2
Is that even possible to achieve just by using annotations?
Hope, things are clearly explained so far. If not, what kind of workaround could I use here? If any info is missing, please let me know.
Thanks a lot.

How to add constraint to collection items

I have an entity with collection of strings. I would like to add a constrains that will check if all items in the collection have size less then 255.
Let's say I have an entity Area with a collection of references. I would like to be sure that all references are shorter then 255 characters. Do you know how can I achieve it.
#Entity
#Table(name = "AREA")
public class Area Serializable {
private static final long serialVersionUID = -4756123949793458708L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", unique = true, nullable = false)
private Integer id;
#ElementCollection
#CollectionTable(name = "AREA_REFERENCES", joinColumns = #JoinColumn(name = "AREA_ID"))
#Column(name = "REFERENCE", nullable = false)
#Size(max = 255) // THIS ANNOTATION SEEMS TO NOT WORK
private Set<String> references = new HashSet<>();
....
Annotating like this
#Size(max = 255)
private Set<String> references;
means the Set<String> is allowed to contain a maximum of 255 strings.
Of course this is not what you want.
Instead, you want each string to have a maximum of 255 characters:
You can achieve it by annotating the type parameter within < > like this:
private Set<#Size(max = 255) String> references;
For that you will need quite new versions of Hibernate Validator (6.0.x)
and Bean Validation (2.0.1).
See also this answer for a similar problem.
According to how-to-limit-the-column-length-while-using-collection-of-primitive-type you could set the size constraint to the Column annotation.
For validation, you could add a like #Size(max=allowed_length) constraint from the Bean Validation API (JSR 303).
Hibernate uses Bean Validation constraints to generate an accurate database schema.
for example :
#Size.max leads to a varchar(max) definition for Strings and
#Min, #Max lead to column checks (like value <= max)

Hibernate Id Sequence Resulting null in Entity having two columns with sequence

I have one Table in postgresql database with two id Sequence.
#JsonProperty("id")
#Column(name = "id", nullable = false,unique=true)
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY,generator = "order_seq_gen")
#SequenceGenerator(name = "order_seq_gen", sequenceName ="order_id_seq")
private Integer id;
#JsonProperty("state")
private String state;
#JsonProperty("order_id")
#Column(name="order_id", nullable=false, unique=true, insertable = false,
updatable = true, columnDefinition = "BIGINT DEFAULT nextval('order_idgen_seq')")
#GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "order_seq_gen")
#SequenceGenerator(name = "order_seq_gen", sequenceName ="order_idgen_seq")
private Integer orderId;
This is my pojo.
My issue with the orderId, if I call my CRUD Repository save it is creating new record with those sequence starting values,
while returning the object orderId is resulting null but it is there in my table.
I have checked with the pojo and column mapping everything is fine but I'm not getting where it went wrong.
Another id sequence is returning without any issue but while coming to orderId it is resulting always null.
Please help me to solve this, Thankful to them.
I didn't think #GeneratedValue worked unless the #Id column was also present.
You could try this instead:
#Generated(GenerationTime.INSERT)
private Integer orderId;
and then make sure your Postgres column was defined as SERIAL type, which will automatically create a sequence named tablename_order_id_seq to use for it.

Is there any way to get unique elements in list when realizing ManyToMany association?

I have Language entity. And I want to realize ManyToMany association with the same table. translation_ways table have just two fields fromLangId int(3) and toLangId int(3).
#Entity(name = "Language")
#Table(name = "language")
public class Language implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "language_id")
private int id;
#NotBlank
#Column(name = "short_name", unique = true, length = 2, nullable = false)
private String shortName;
#NotBlank
#Column(name = "full_name", unique = true, nullable = false)
private String fullName;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "translation_ways",
joinColumns = #JoinColumn(name = "fromLangId"),
inverseJoinColumns = #JoinColumn(name = "toLangId"))
private Set<Language> toLangs;
//getters and setters here
//ovverrided equals() & hashCode()
}
What I want to do is to get the list of all Languages (with Set of the Languages entities joined by translation_ways table). The problem is that Criteria.list() returns list with duplicates. Amount of duplicates in the list is equal to how many times current id appears in the translation_ways.fromLangId column. In my case it is redundant information and I want to get list of unique Objects.
So the first question is if there is the some recommended or best of the best way to get this list without redundant elements? Convert returned ArrayList to LinkedHashSet? Or maybe I just did something wrong with my Criteria???
Also, have one more related question. If I'll call this query in the second time hibernate will take data from a cache, am I right?
I will appreciate any recommendations, ideas, links and help. Thanks everyone in advance.
my request:
Criteria c = this.template.getSessionFactory().getCurrentSession().createCriteria(Language.class);
c.setCacheable(true)
.setCacheMode(CacheMode.NORMAL)
.setCacheRegion("staticLangList");
List<Language> ls = c.list();
return ls;
P.S. Hibernate version is 5.0.1.Final.
use setResultTransformer in Criteria to avoid duplicates.
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

How to exclude an entity field when doing an update with JPA

Is there a way to make a field non-persistent at update operation but persistent at create operation with JPA - Hibernate 4?
I tried it in this way
#Transient
#Id
#Column(name = "USER_NAME", nullable = false, length = 75)
private String userName;
but with #Transient annotation the field will be transient across all CRUD operations and I want a way to specify that only on this operation is persistent (create).
Is there a way to do this?
Thanks!
You need to set updatable attribute of the #Column annotation to false:
#Column(name = "USER_NAME", nullable = false, length = 75, updatable= false)
private String userName;
The updatable attribute instruct Hibernate to omit this column from the generated UPDATE SQL statement.
I removed the #Transient and the #Id annotations.
If this column is your PK (mapped to the entity identifier), then you can only set it during INSERT, since Hibernate doesn't allow you to update an entity identifier (the updatable attribute being redundant in this case).

Categories

Resources