There are lots of questions about this in StackOverflow. But l still can't solve it.
I am coding a tax system using Hibernate as my persistence layer.
Now, l have two entity classes:
Role.java and RolePrivilege.java.
this is Role.java
package com.taxsys.nsfw.role.entity;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name="role")
public class Role implements Serializable{
#Id
#GenericGenerator(name="pk_hilo", strategy="hilo")
#GeneratedValue(generator="pk_hilo")
#Column(name="role_id")
private String roleId;
#Column(name="role_name",length=32, nullable=false)
private String roleName;
#Column(name="state", length=1)
private String state;
#OneToMany(targetEntity=RolePrivilege.class,
mappedBy="role", cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
private Set<RolePrivilege> role = new HashSet<>();
public static String ROLE_STATE_VALID = "1";
public static String ROLE_STATE_INVALID = "0";
public Set<RolePrivilege> getRolePrivilege() {
return role;
}
public void setRolePrivilege(Set<RolePrivilege> rolePrivilege) {
this.role = rolePrivilege;
}
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Role() {
}
public Role(String roleId, String roleName, String state, Set<RolePrivilege> rolePrivilege) {
super();
this.roleId = roleId;
this.roleName = roleName;
this.state = state;
this.role = rolePrivilege;
}
}
this is RolePrivilege.java:
package com.taxsys.nsfw.role.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="role_privilege")
public class RolePrivilege implements Serializable{
#ManyToOne(targetEntity=Role.class, fetch=FetchType.EAGER)
#JoinColumn(name="role_id", referencedColumnName="role_id")
#Id
private Role role;
#Id
private String code;
public RolePrivilege(Role role, String code) {
super();
this.role = role;
this.code = code;
}
public RolePrivilege() {
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
result = prime * result + ((role == null) ? 0 : role.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RolePrivilege other = (RolePrivilege) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
if (role == null) {
if (other.role != null)
return false;
} else if (!role.equals(other.role))
return false;
return true;
}
}
I am using Hibernate3.6,spring3.0,struts2.3 and tomcat7.
But when l start Tomcat, the error message will be showing:
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.taxsys.nsfw.role.entity.RolePrivilege.role in com.taxsys.nsfw.role.entity.Role.role
Look my code! mappedBy="role".It's the same with RolePrivilege.role!And even if l use lower-case, it doesn't work! I don't know why. Maybe it is a question about jar or compatibility? Thank you!
Remove #Id in RolePrivilege.java for private Role role; and report back what error are u still getting
You can map the composite key using #Embeddable annotation in a new class object, then use #ManyToOne mapping to map the child object to the parent object. See Hibernate annotations to map one to one unidirectional association with composite primary key
Related
I have three entity classes Country, State, and City. Now I am trying to display the cities that come under a particular state and states that come under a particular country. but I am facing an error like
org.springframework.dao.DataAccessResourceFailureException:
Could not create JPA EntityManager;
nested exception is org.hibernate.AnnotationException:
#OneToOne or #ManyToOne on com.region.model.State.cities reference
an unknown entity: java.util.List.
Please help me out in one-to-many and many-to-one mapping for the three tables.
package com.region.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
#Entity
#Table(name = "country")
public class Country {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private Integer country_id;
#Column
private String country_name;
// #Column
// private String status="active";
#Transient
private String statusCode;
#Transient
private String statusmessage;
#OneToMany(targetEntity=State.class, mappedBy="country",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
#JsonBackReference
private List<State> states;
public Country() {
}
public Integer getCountry_id() {
return country_id;
}
public void setCountry_id(Integer country_id) {
this.country_id = country_id;
}
public String getCountry_name() {
return country_name;
}
public void setCountry_name(String country_name) {
this.country_name = country_name;
}
// public String getStatus() {
// return status;
// }
// public void setStatus(String status) {
// this.status = status;
// }
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getStatusmessage() {
return statusmessage;
}
public void setStatusmessage(String statusmessage) {
this.statusmessage = statusmessage;
}
public List<State> getStates() {
return states;
}
public void setStates(List<State> states) {
this.states = states;
}
}
package com.region.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
#Entity
#Table(name = "state")
public class State {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private Integer sk_state_id;
#Column
private String state_name;
#Column
private String country_id;
// #Column
// private String status="active";
#Transient
private String statusCode;
#Transient String statusMessage;
#ManyToOne()
#JoinColumn(name="country_id", referencedColumnName = "country_id", insertable = false, updatable = false)
#JsonManagedReference
#OneToMany(targetEntity=City.class, mappedBy="state",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private List<City>cities;
private Country country;
public State() {
}
public Integer getSk_state_id() {
return sk_state_id;
}
public void setSk_state_id(Integer sk_state_id) {
this.sk_state_id = sk_state_id;
}
public String getState_name() {
return state_name;
}
public void setState_name(String state_name) {
this.state_name = state_name;
}
public String getCountry_id() {
return country_id;
}
public void setCountry_id(String country_id) {
this.country_id = country_id;
}
// public String getStatus() {
// return status;
// }
// public void setStatus(String status) {
// this.status = status;
// }
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getStatusMessage() {
return statusMessage;
}
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
}
package com.region.model;
import java.lang.annotation.Repeatable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
#Entity
#Table(name = "city")
public class City {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private Integer sk_city_id;
#Column
private String city_name;
#Column
private String state_id;
#Column
private String country_id;
#Transient
private String statusCode;
#Transient
String statusMessage;
#ManyToOne(targetEntity = State.class)
#JoinColumn(name="state_id", referencedColumnName ="sk_state_id", insertable = false, updatable = false)
private State state;
private Country country;
//private List<State>states;
public City() {
}
public Integer getSk_city_id() {
return sk_city_id;
}
public void setSk_city_id(Integer sk_city_id) {
this.sk_city_id = sk_city_id;
}
public String getCity_name() {
return city_name;
}
public void setCity_name(String city_name) {
this.city_name = city_name;
}
public String getState_id() {
return state_id;
}
public void setState_id(String state_id) {
this.state_id = state_id;
}
public String getCountry_id() {
return country_id;
}
public void setCountry_id(String country_id) {
this.country_id = country_id;
}
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getStatusMessage() {
return statusMessage;
}
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
#Override
public String toString() {
return "City [sk_city_id=" + sk_city_id + ", city_name=" + city_name + ", state_id=" + state_id
+ ", country_id=" + country_id + ", statusCode=" + statusCode + ", statusMessage=" + statusMessage
+ "]";
}
// public List<State> getStates() {
// return states;
// }
// public void setStates(List<State> states) {
// this.states = states;
// }
}
mappedBy is only used once in a relationship between 2 classes, for the class that you want to define the relationship for both. So in the class Countries you probably don't need mappedBy at all, in the class Cities, you should put mappedBy="state", and in the class State it would make sense to put mappedBy="country"
I have two tables device_data and device_connection. I want to join these two tables on basis of column customerId. Both the tables have customerId column.
DeviceData
import java.io.Serializable;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "device_data")
public class DeviceData implements Serializable,Cloneable {
#Id
#Column(name = "identifier")
private BigInteger identifier;
#Id
#Column(name = "device_time")
private Timestamp deviceTime;
#Column(name = "ctr_id")
private BigInteger customerId;
#Column(name = "signal_strength")
private Double signalStrength;
#OneToOne
#JoinColumn(name = "ctr_id", nullable = false, insertable = false, updatable = false, referencedColumnName = "ctr_id")
private DeviceConnection deviceConnection;
public BigInteger getIdentifier() {
return identifier;
}
public DeviceData setIdentifier(BigInteger identifier) {
this.identifier = identifier;
return this;
}
public Timestamp getDeviceTime() {
return deviceTime;
}
public DeviceData setDeviceTime(Timestamp deviceTime) {
this.deviceTime = deviceTime;
return this;
}
public BigInteger getCustomerId() {
return customerId;
}
public DeviceData setCustomerId(BigInteger customerId) {
this.customerId = customerId;
return this;
}
public DeviceConnection getDeviceConnection() {
return deviceConnection;
}
public DeviceData setDeviceConnection(
DeviceConnection deviceConnection) {
this.deviceConnection = deviceConnection;
return this;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DeviceData that = (DeviceData) o;
return identifier.equals(that.identifier) &&
deviceTime.equals(that.deviceTime);
}
#Override
public int hashCode() {
return Objects.hash(identifier, deviceTime);
}
}
DeviceConnection
import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
#Entity
#Table(name = "device_connection")
public class DeviceConnection implements Serializable , Cloneable {
public DeviceConnection() {
}
#Column(name = "id")
private BigInteger id;
#Column(name = "ctr_id")
private BigInteger customerId;
#Column(name = "low_signal_strength_limit")
private Integer lowSignalStrengthLimit;
public BigInteger getCustomerId() {
return customerId;
}
public DeviceConnection setCustomerId(BigInteger customerId) {
this.customerId = customerId;
return this;
}
public Integer getLowSignalStrengthLimit() {
return lowSignalStrengthLimit;
}
public DeviceConnection setLowSignalStrengthLimit(
Integer lowSignalStrengthLimit) {
this.lowSignalStrengthLimit = lowSignalStrengthLimit;
return this;
}
public BigInteger getId() {
return id;
}
public DeviceConnection setId(BigInteger id) {
this.id = id;
return this;
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DeviceConnection that = (DeviceConnection) o;
return Objects.equals(getId(), that.getId());
}
#Override
public int hashCode() {
return Objects.hash(getId());
}
}
I wrote a Query to get data from join of these two tables.
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<DeviceData> cq = cb.createQuery(DeviceData.class);
Root<DeviceData> root = cq.from(DeviceData.class);
Join<DeviceData, DeviceConnection> join = (Join<DeviceData, DeviceConnection>) root
.fetch(DeviceData_.deviceConnection);
List<Predicate> conditions = new ArrayList<>();
conditions.add(cb.equal(root.get(DeviceData_.CUSTOMER_ID), join.get(
DeviceConnection_.CUSTOMER_ID)));
conditions.add(cb.greaterThanOrEqualTo(root.get(DeviceData_.DEVICE_TIME),
config.getDataStartTime()));
if (isNotNull(config.getDataEndTime())) {
conditions.add(cb.lessThanOrEqualTo(root.get(DeviceData_.DEVICE_TIME),
config.getDataEndTime()));
}
cq.where(conditions.toArray(new Predicate[]{}))
.orderBy(cb.asc(root.get(DeviceData_.DEVICE_TIME)));
return session.createQuery(cq);
And I set the property SHOW_SQL to TRUE. So, here is the query which hibernate generate.
select
devicedata0_.occurrence_time as occurren1_3_0_, devicedata0_.identifier as identifier2_3_0_, connection1_.id as id1_0_1_, devicedata0_.ctr_id as ctr_id9_3_0_, devicedata0_.signal_strength as signal_15_3_0_, connection1_.ctr_id as ctr_id7_0_1_, connection1_.low_signal_strength_limit as low_sig14_0_1_
from
device_data devicedata0_
inner join device_connection connection1_ on
devicedata0_.ctr_id=connection1_.ctr_id
where
devicedata0_.ctr_id=connection1_.ctr_id and
devicedata0_.created_at>='2018-06-12 12:00:00'
order by
devicedata0_.created_at asc
limit 2000;
when i run this Query on My Sql workbench it will work expected and give me results. But hibernate constantly giving me exception i don't know why?
Exception
java.lang.ClassCastException: com.sbi.model.DeviceConnection cannot be cast to java.math.BigInteger
I have 2 different tables: subjects and questions and I need to make SQL JOIN on these 2 tables. Table subjects has its attributes: name and shortcut. Table questions has its attributes: question_number, text, subject - in fact, subject from table questions is a shortcut of a subject.
I tried something like this, what I saw in one stackoverflow topic:
Query q = em.createNativeQuery("SELECT q.question_number, q.text, s.name, s.shortcut FROM "
+ "( questions q INNER JOIN subjects s ON q.subject=s.shortcut );", QuestionSubject.class);
QuestionSubject.class is an #Entity class and has attributes of both questions table and subjects table. After calling this method I saw that a new table with a name QUESTIONSUBJECT was created in my database and that is what I do not want to be done.
Can anyone help me with other solution?
P.S.: I am doing this in order to use the ouput as a response on HTTP request so I need to gather those two into one. I need to return either a List or JSON string.
EDIT: Using MySQL database.
questions table Entity class:
package model;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "questions")
#XmlRootElement
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Basic(optional = false)
#Column(name = "question_number")
private Integer questionNumber;
#Column(name = "text")
private String text;
#Column(name = "subject")
private String subject;
public Question() {
}
public Question(Integer questionNumber) {
this.questionNumber = questionNumber;
}
public Question( String text, String subject) {
this.text = text;
this.subject = subject;
}
public Question(Integer questionNumber, String text, String subject) {
this.questionNumber = questionNumber;
this.text = text;
this.subject = subject;
}
public Integer getQuestionNumber() {
return questionNumber;
}
public void setQuestionNumber(Integer questionNumber) {
this.questionNumber = questionNumber;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
#Override
public int hashCode() {
int hash = 0;
hash += (questionNumber != null ? questionNumber.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Question)) {
return false;
}
Question other = (Question) object;
if ((this.questionNumber == null && other.questionNumber != null) || (this.questionNumber != null && !this.questionNumber.equals(other.questionNumber))) {
return false;
}
return true;
}
#Override
public String toString() {
return "Rest.Questions[ questionNumber=" + questionNumber + " ]";
}
}
subjects table Entity class.
package model;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "subjects")
#XmlRootElement
public class Subject implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 5)
#Column(name = "shortcut")
private String shortcut;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "name")
private String name;
public Subject() {
}
public Subject(String shortcut) {
this.shortcut = shortcut;
}
public Subject(String shortcut, String name) {
this.shortcut = shortcut;
this.name = name;
}
public String getShortcut() {
return shortcut;
}
public void setShortcut(String shortcut) {
this.shortcut = shortcut;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
int hash = 0;
hash += (shortcut != null ? shortcut.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Subject)) {
return false;
}
Subject other = (Subject) object;
if ((this.shortcut == null && other.shortcut != null) || (this.shortcut != null && !this.shortcut.equals(other.shortcut))) {
return false;
}
return true;
}
#Override
public String toString() {
return "Rest.Subjects[ shortcut=" + shortcut + " ]";
}
}
QuestionSubject Entity class:
package model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class QuestionSubject implements Serializable
{
#Id
#Column(name = "question_number")
private Integer questionNumber;
#Column(name = "text")
private String text;
#Column(name = "shortcut")
private String shortcut;
#Column(name = "name")
private String name;
public Integer getQuestionNumber() {
return questionNumber;
}
public void setQuestionNumber(Integer questionNumber) {
this.questionNumber = questionNumber;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getShortcut() {
return shortcut;
}
public void setShortcut(String shortcut) {
this.shortcut = shortcut;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The table gets created because you define a class named QuestionSubject annotated as #Entity. Per default the table name is the class name.
You could override the name like you did in Subjects with #Table(name = "subjects")
Nearly the same would happen if you would define a #ManyToMany mapping on related fields between classes Question and Subject without defining QuestionSubject class at all.
I would recommend to take a look here to get more information:
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Relationship_Mappings/Collection_Mappings/ManyToMany
Edit
If you need a manyToMany mapping you need this table. Otherwise you can only have an oneToMany resp. manyToOne relation (using foreign keys).
I have a JPA inheritance with a class ContactDTO that is extended by UserDTO with Single_Table strategy:
package ch.ffhs.cryptomess.server.dto;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.persistence.Version;
import org.springframework.transaction.annotation.Transactional;
#Transactional
#Entity(name = "ch.ffhs.cryptomess.server.dto.ContactDTO")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
#DiscriminatorValue(value = "ContactDTO")
#Table(name = "user", uniqueConstraints = #UniqueConstraint(columnNames = {
"username", "discriminator" }))
public class ContactDTO implements Serializable {
private static final long serialVersionUID = 7706720499337697645L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_id_seq")
#SequenceGenerator(name = "user_id_seq", allocationSize = 1, initialValue = 10)
#Column(name = "id")
protected Long id;
#Version
protected Long version;
#Column(name = "public_key", length = 255)
protected String publicKey;
#Id
#Column(length = 50, updatable = false)
protected String username;
#ManyToMany(mappedBy = "contacts", targetEntity = CommunicationDTO.class)
protected Set<CommunicationDTO> communications = new HashSet<CommunicationDTO>(
0);
#Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final ContactDTO other = (ContactDTO) obj;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
public Set<CommunicationDTO> getCommunications() {
return communications;
}
public Long getId() {
return id;
}
public String getPublicKey() {
return publicKey;
}
public String getUsername() {
return username;
}
public Long getVersion() {
return version;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
public void setCommunications(final Set<CommunicationDTO> communications) {
this.communications = communications;
}
public void setId(final Long id) {
this.id = id;
}
public void setPublicKey(final String publicKey) {
this.publicKey = publicKey;
}
public void setUsername(final String username) {
this.username = username;
}
public void setVersion(final Long version) {
this.version = version;
}
}
and:
package ch.ffhs.cryptomess.shared.dto;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.springframework.transaction.annotation.Transactional;
import ch.ffhs.cryptomess.server.dto.ContactDTO;
import com.google.gwt.view.client.ProvidesKey;
#Transactional
#Entity
#DiscriminatorValue(value = "UserDTO")
public class UserDTO extends ContactDTO implements Serializable {
private static final long serialVersionUID = -3078472527069117428L;
#Column(length = 80)
protected String password;
#Column(name = "is_account_non_expired", columnDefinition = "BIT")
protected boolean isAccountNonExpired;
#Column(name = "is_account_locked", columnDefinition = "BIT")
protected boolean isAccountLocked;
#Column(name = "is_credentials_non_expired", columnDefinition = "BIT")
protected boolean isCredentialsNonExpired;
#Column(name = "is_disabled", columnDefinition = "BIT")
protected boolean isDisabled;
/**
* The key provider that provides the unique ID of a contact.
*/
public static final ProvidesKey<UserDTO> KEY_PROVIDER = new ProvidesKey<UserDTO>() {
#Override
public Object getKey(final UserDTO item) {
return item == null ? null : item.getId();
}
};
public String getPassword() {
return password;
}
public boolean isAccountLocked() {
return isAccountLocked;
}
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}
public boolean isAccountNonLocked() {
return !isAccountLocked;
}
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}
public boolean isDisabled() {
return isDisabled;
}
public boolean isEnabled() {
return !isDisabled;
}
public void setAccountLocked(final boolean isAccountLocked) {
this.isAccountLocked = isAccountLocked;
}
public void setAccountNonExpired(final boolean isAccountNonExpired) {
this.isAccountNonExpired = isAccountNonExpired;
}
public void setAccountNonLocked(final boolean isAccountNonLocked) {
this.isAccountLocked = !isAccountNonLocked;
}
public void setCredentialsNonExpired(final boolean isCredentialsNonExpired) {
this.isCredentialsNonExpired = isCredentialsNonExpired;
}
public void setDisabled(final boolean isDisabled) {
this.isDisabled = isDisabled;
}
public void setEnabled(final boolean isEnabled) {
this.isDisabled = !isEnabled;
}
public void setPassword(final String password) {
this.password = password;
}
}
If I do a merge or create on an UserDTO-enity, I want the ContactDTO-entity to be created/updated as well in the database. Is there any way to achieve this, without handling both entities seperately?
Thank you for helping!
I was trying to implement hibernate one-to-one bidirectional mapping between Person class and Address class using annotation. While running the program it gave me some errors
org.hibernate.TransientObjectException: object references an unsaved transient
instance - save the transient instance before flushing: com.vaannila.domain.Person
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:242)
at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:597)
at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3123)
at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:479)
at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:204)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:127)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.vaannila.domain.Add.main(Add.java:58)
following are my classes
Person.java
package com.vaannila.domain;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "PERSON")
public class Person implements Serializable {
private long personId;
private String personName;
private Address personAddress;
private Set<Phone> personPhoneNumbers = new HashSet<Phone>(0);
public Person() {
}
public Person(String personName, Address personAddress, Set<Phone> personPhoneNumbers) {
this.personName = personName;
this.personAddress = personAddress;
this.personPhoneNumbers = personPhoneNumbers;
}
#Id
#GeneratedValue
#Column(name = "PERSON_ID")
public long getPersonId() {
return this.personId;
}
public void setPersonId(long personId) {
this.personId = personId;
}
#Column(name = "PERSON_NAME", nullable = false, length = 100)
public String getPersonName() {
return this.personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
#OneToOne(cascade = CascadeType.ALL)
public Address getPersonAddress() {
return this.personAddress;
}
public void setPersonAddress(Address personAddress) {
this.personAddress = personAddress;
}
#OneToMany
#JoinTable(name = "PERSON_PHONE", joinColumns =
{ #JoinColumn(name = "PERSON_ID") }, inverseJoinColumns =
{ #JoinColumn(name = "PHONE_ID") })
public Set<Phone> getPersonPhoneNumbers() {
return personPhoneNumbers;
}
public void setPersonPhoneNumbers(Set<Phone> personPhoneNumbers) {
this.personPhoneNumbers = personPhoneNumbers;
}
}
Addres.java
package com.vaannila.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "ADDRESS")
public class Address implements Serializable {
private long addressId;
private String street;
private String city;
private String state;
private String zipcode;
private Person person;
public Address() {
}
#Id
#GeneratedValue
#Column(name = "ADDRESS_ID")
public long getAddressId() {
return this.addressId;
}
public void setAddressId(long addressId) {
this.addressId = addressId;
}
#Column(name = "ADDRESS_STREET", nullable = false, length=250)
public String getStreet() {
return this.street;
}
public void setStreet(String street) {
this.street = street;
}
#Column(name = "ADDRESS_CITY", nullable = false, length=50)
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
#Column(name = "ADDRESS_STATE", nullable = false, length=50)
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
#Column(name = "ADDRESS_ZIPCODE", nullable = false, length=10)
public String getZipcode() {
return this.zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
#OneToOne
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Phone.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.vaannila.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*
* #author junaid
*/
#Entity
#Table(name = "PHONE")
public class Phone implements java.io.Serializable {
private long phoneId;
private String phoneType;
private String phoneNumber;
public Phone() {
}
public Phone(String phoneType, String phoneNumber) {
this.phoneType = phoneType;
this.phoneNumber = phoneNumber;
}
#Id
#GeneratedValue
#Column(name = "PHONE_ID")
public long getPhoneId() {
return this.phoneId;
}
public void setPhoneId(long phoneId) {
this.phoneId = phoneId;
}
#Column(name = "PHONE_TYPE", nullable = false, length=10)
public String getPhoneType() {
return this.phoneType;
}
public void setPhoneType(String phoneType) {
this.phoneType = phoneType;
}
#Column(name = "PHONE_NUMBER", nullable = false, length=15)
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
Main class
package com.vaannila.domain;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.vaannila.util.HibernateUtil;
import java.util.HashSet;
import java.util.Set;
public class Add {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
//Transaction for person 1 start
Address address1 = new Address();
address1.setCity("Bangalore");
address1.setState("Karnataka");
address1.setStreet("Ring Road");
address1.setZipcode("560000");
Set<Phone> phoneNumbers = new HashSet<Phone>();
phoneNumbers.add(new Phone("house","32354353"));
phoneNumbers.add(new Phone("mobile","9889343423"));
Person person = new Person();
person.setPersonName("Junaid");
person.setPersonAddress(address1);
person.setPersonPhoneNumbers(phoneNumbers);
session.save(person);
//Transaction for person 1 end
//Transaction for person 2 start
Set<Phone> phoneNumbers2 = new HashSet<Phone>();
phoneNumbers2.add(new Phone("house","32354353"));
phoneNumbers2.add(new Phone("mobile","9889343423"));
Person person1 = new Person();
person1.setPersonName("Wayne");
person1.setPersonPhoneNumbers(phoneNumbers2);
Address address2 = new Address();
address2.setCity("Chennai");
address2.setState("Tamil Nadu");
address2.setStreet("OMR Road");
address2.setZipcode("4000");
address2.setPerson(person1);
session.save(address2);
//Transaction for person 2 end
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
All tables are getting created, but when deleting the table, all except Person and Address is not getting deleted.
Can anyone please help me?
Thanks in advance.
Got it working guys.
i missed out mappedBy property. After adding that its working fine.
#OneToOne(mapperdBy="personAddress")
public Person getPerson() {
return person;
}