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!
Related
I have an auditing entity which defined like this:
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.io.Serializable;
import java.time.Instant;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
/**
* Base abstract class for entities which will hold definitions for created, last modified, created by,
* last modified by attributes.
*/
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#CreatedBy
#Column(name = "created_by", nullable = false, length = 50, updatable = false)
#JsonIgnore
private String createdBy;
#CreatedDate
#Column(name = "created_date", updatable = false)
#JsonIgnore
private Instant createdDate = Instant.now();
#LastModifiedBy
#Column(name = "last_modified_by", length = 50)
#JsonIgnore
private String lastModifiedBy;
#LastModifiedDate
#Column(name = "last_modified_date")
#JsonIgnore
private Instant lastModifiedDate = Instant.now();
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Instant getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public Instant getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Instant lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
And this is the implementation:
import com.app.derin.uaa.config.Constants;
import java.util.Optional;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
/**
* Implementation of {#link AuditorAware} based on Spring Security.
*/
#Component
public class SpringSecurityAuditorAware implements AuditorAware<String> {
#Override
public Optional<String> getCurrentAuditor() {
return Optional.of(SecurityUtils.getCurrentUserName().orElse(Constants.SYSTEM_ACCOUNT));
}
}
But I also need to store Hostname of request ip ( if it can be acquired from browser/dns if not it can be null) and request ip.
I found some examples and i changed my class to this:
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.ColumnDefault;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity<T> implements Serializable {
#CreatedDate
#JsonIgnore
#Column(name = "created_date", updatable = false)
private Instant createdDate = Instant.now();
#CreatedBy
#JsonIgnore
#Column(name = "created_by", updatable = false)
#Embedded
private T createdBy;
#LastModifiedDate
#Column(name = "modified_date")
#JsonIgnore
private Instant modifiedDate = Instant.now();;
#LastModifiedBy
#Column(name = "modified_by")
#JsonIgnore
#Embedded
private T modifiedBy;
public Instant getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public T getCreatedBy() {
return createdBy;
}
public void setCreatedBy(T createdBy) {
this.createdBy = createdBy;
}
public Instant getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Instant modifiedDate) {
this.modifiedDate = modifiedDate;
}
public T getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(T modifiedBy) {
this.modifiedBy = modifiedBy;
}
}
And my implementation to this:
import com.app.derin.configuration.config.Constants;
import java.util.Optional;
import com.app.derin.configuration.ext.AuditorDetails;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
/**
* Implementation of {#link AuditorAware} based on Spring Security.
*/
#Component
public class SpringSecurityAuditorAware implements AuditorAware<AuditorDetails> {
#Override
public Optional<AuditorDetails> getCurrentAuditor() {
AuditorDetails currentAuditor = new AuditorDetails();
currentAuditor.setLoggedUser(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT));
currentAuditor.setHostIp("ip");
return Optional.of(currentAuditor);
}
}
But if I am right hibernate doesn't support generic types. I am getting this error:
[ERROR] Error setting up or running Liquibase:
[ERROR] org.hibernate.AnnotationException: Property com.app.derin.configuration.ext.extendedFields.AbstractAuditingEntity.createdBy has an unbound type and no explicit target entity. Resolve this Generic usage issue or set an explicit targe
t attribute (eg #OneToMany(target=) or use an explicit #Type
Is there any way to achieve this?
I found solution and here is how did:
After a lot of googling i found that my problem is with hibernate annotation. I am trying to send Datatype that hibernate doesn't know about. So I changed my class to custom type for hibernate.
More info you can check this link. It helped me.
My AuditorDetails class:
import java.io.Serializable;
import java.util.Objects;
public final class AuditorDetails implements Serializable {
private final String loggedUser;
private final String hostName;
private final String hostIp;
public AuditorDetails(String loggedUser, String hostName, String hostIp) {
this.loggedUser = loggedUser;
this.hostName = hostName;
this.hostIp = hostIp;
}
public String getLoggedUser() {
return loggedUser;
}
public String getHostName() {
return hostName;
}
public String getHostIp() {
return hostIp;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AuditorDetails that = (AuditorDetails) o;
return Objects.equals(loggedUser, that.loggedUser) &&
Objects.equals(hostName, that.hostName) &&
Objects.equals(hostIp, that.hostIp);
}
#Override
public int hashCode() {
return Objects.hash(loggedUser, hostName, hostIp);
}
}
AuditorDetailsType class:
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class AuditorDetailsType implements UserType {
#Override
public int[] sqlTypes() {
return new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR};
}
#Override
public Class returnedClass() {
return AuditorDetails.class;
}
#Override
public boolean equals(Object o, Object o1) throws HibernateException {
if(o == o1)
return true;
if (Objects.isNull(o) || Objects.isNull(o1))
return false;
return o.equals(o1);
}
#Override
public int hashCode(Object o) throws HibernateException {
return o.hashCode();
}
#Override
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException, SQLException {
String loggedUser = resultSet.getString(strings[0]);
if(resultSet.wasNull())
return null;
String hostName = resultSet.getString(strings[1]);
String hostIp = resultSet.getString(strings[2]);
AuditorDetails currentAuditor = new AuditorDetails(loggedUser, hostName, hostIp);
return currentAuditor;
}
#Override
public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SharedSessionContractImplementor sharedSessionContractImplementor) throws HibernateException, SQLException {
if (Objects.isNull(o)){
preparedStatement.setNull(i,Types.VARCHAR);
}
else {
AuditorDetails currentAuditor = (AuditorDetails) o;
preparedStatement.setString(i,currentAuditor.getLoggedUser());
preparedStatement.setString(i+1,currentAuditor.getHostName());
preparedStatement.setString(i+2,currentAuditor.getHostIp());
}
}
#Override
public Object deepCopy(Object o) throws HibernateException {
if (Objects.isNull(o))
return null;
AuditorDetails currentAuditor = (AuditorDetails) o;
return new AuditorDetails(currentAuditor.getLoggedUser(), currentAuditor.getHostName(), currentAuditor.getHostIp());
}
#Override
public boolean isMutable() {
return false;
}
#Override
public Serializable disassemble(Object o) throws HibernateException {
return (Serializable) o;
}
#Override
public Object assemble(Serializable serializable, Object o) throws HibernateException {
return serializable;
}
#Override
public Object replace(Object o, Object o1, Object o2) throws HibernateException {
return o;
}
}
AbstractAuditingEntity:
import com.app.derin.uaa.ext.AuditorDetails;
import com.app.derin.uaa.ext.AuditorDetailsType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Columns;
import org.hibernate.annotations.TypeDef;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.Instant;
#TypeDef(name = "AuditorDetails",
typeClass = AuditorDetailsType.class,
defaultForType = AuditorDetails.class)
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity{
#CreatedDate
#JsonIgnore
#Column(name = "created_date", updatable = false)
private Instant createdDate = Instant.now();
#CreatedBy
#Columns(columns = {#Column(name = "created_by", updatable = false),
#Column(name = "created_host_name", updatable = false),
#Column(name = "created_host_ip", updatable = false)})
private AuditorDetails createdBy;
#LastModifiedDate
#Column(name = "modified_date")
#JsonIgnore
private Instant modifiedDate = Instant.now();
#LastModifiedBy
#Columns(columns = {#Column(name = "modified_by"),
#Column(name = "modified_host_name"),
#Column(name = "modified_host_ip")})
private AuditorDetails modifiedBy;
#Column(name = "row_status")
#JsonIgnore
#ColumnDefault("1")
private Integer rowStatus = 1;
protected AbstractAuditingEntity() {
}
public AuditorDetails getModifiedBy() {
return modifiedBy;
}
public Instant getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public AuditorDetails getCreatedBy() {
return createdBy;
}
public void setCreatedBy(AuditorDetails createdBy) {
this.createdBy = createdBy;
}
public Instant getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Instant modifiedDate) {
this.modifiedDate = modifiedDate;
}
public Integer getRowStatus() {
return rowStatus;
}
public void setRowStatus(Integer rowStatus) {
this.rowStatus = rowStatus;
}
}
SpringSecurityAuditorAware:
import com.app.derin.uaa.config.Constants;
import java.util.Optional;
import com.app.derin.uaa.ext.AuditorDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Implementation of {#link AuditorAware} based on Spring Security.
*/
#Component
public class SpringSecurityAuditorAware implements AuditorAware<AuditorDetails> {
private final Logger log = LoggerFactory.getLogger(SpringSecurityAuditorAware.class);
#Override
public Optional<AuditorDetails> getCurrentAuditor() {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
if(request != null) {
String hostIp = getClientIpAddress(request);
String hostName = "";
AuditorDetails currentAuditor = new AuditorDetails(SecurityUtils.getCurrentUserName().orElse(Constants.SYSTEM_ACCOUNT),
hostName, hostIp);
return Optional.of(currentAuditor);
}
return Optional.of(currentAuditor);
}
private static final String[] IP_HEADER_CANDIDATES = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"REMOTE_ADDR" };
public String getClientIpAddress(HttpServletRequest request) {
for (String header : IP_HEADER_CANDIDATES) {
String ip = request.getHeader(header);
log.info("ip : {}", ip);
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
return ip;
}
}
return request.getRemoteAddr();
}
}
I am using Spring data PageRequest to search data based on user filter. I need my sort column to be dynamic along with search filters.
However stateMaster.countryMaster.description, stateMaster.description, description code is not working and throws following error.
org.springframework.data.mapping.PropertyReferenceException: No property description, stateMaster found for type CountryMaster! Traversed path: DistrictMaster.stateMaster.countryMaster.
Here's my service code.
String sortColumn = filterJson.getString("sortColumn");
if ("default".equalsIgnoreCase(filterJson.getString("sortColumn"))) {
sortColumn = "stateMaster.countryMaster.description, stateMaster.description, description";
} else {
sortColumn = "description";
}
String sortOrder = filterJson.getString("sortOrder");
Integer maxResult = Integer.parseInt(hbsService.getGeneralConfigValue("adminmaxallowedlisting"));
PageRequest pageRequest = new PageRequest(pageNo, maxResult, Sort.Direction.valueOf(sortOrder), sortColumn);
Page<DistrictMaster> page = districtRepository.findAll(new Specification<DistrictMaster>() {
#Override
public Predicate toPredicate(Root<DistrictMaster> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
if (filterJson.optLong("stateId") != 0) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("stateMaster"), filterJson.optLong("stateId"))));
}
if (!filterJson.optString("status").trim().isEmpty() && !filterJson.optString("status").equals("All")) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("active"), filterJson.optBoolean("status"))));
}
if (!filterJson.optString("value").trim().isEmpty()) {
predicates.add(criteriaBuilder.and(criteriaBuilder.like(criteriaBuilder.lower(root.get("description")), "%" + filterJson.optString("value").toLowerCase() + "%")));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
}, pageRequest);
Here's my model:
package com.agrisk.data.model;
import java.io.Serializable;
import java.util.Set;
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.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "tbldistrictmst")
#SequenceGenerator(name = "districtmstseq", allocationSize = 1, sequenceName = "districtmstseq")
public class DistrictMaster extends MakerCheckerBO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5461420398663313529L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "districtmstseq")
#Column(name = "id")
public Long id;
#Column(name = "description")
public String description;
#Column(name = "code")
public String code;
#ManyToOne
#JoinColumn(name = "stateid")
private StateMaster stateMaster;
#Column(name = "active")
public Boolean active;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "districtid")
public Set<TehsilMaster> tehsilMaster;
#Column(name = "villagereferenceid")
private Long villageReferenceId;
public Set<TehsilMaster> getTehsilMaster() {
return tehsilMaster;
}
public void setTehsilMaster(Set<TehsilMaster> tehsilMaster) {
this.tehsilMaster = tehsilMaster;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public StateMaster getStateMaster() {
return stateMaster;
}
public void setStateMaster(StateMaster stateMaster) {
this.stateMaster = stateMaster;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Long getVillageReferenceId() {
return villageReferenceId;
}
public void setVillageReferenceId(Long villageReferenceId) {
this.villageReferenceId = villageReferenceId;
}
}
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
Im having trouble making the datepicker( angularjs-datepicker 720kb.datepicker), it keeps returning dates 1 day before of what it should.
<div class="col-md-5">
<label>Fecha Disposicion</label>
<datepicker date-format="yyyy-MM-dd" date-year-title="selected year">
<input ng-model="vm.auto.fechaDisposicion" />
</datepicker>
</div>
Im using UTC time for the rest of my app, and the back end is springboot data rest and the database mysql (datetime).
Here's the suggested workaround in the git hub proyect, but I don't really get how to implement it.
Output before POST method: "2018-01-03"
Arrives at the DB like this: "2018-01-02 00:00:00"
MY java controller:
package ar.gob.snr.expediente.domain;
import java.io.Serializable;
import java.sql.Date;
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.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.springframework.data.rest.core.annotation.RestResource;
#Entity
#Table(name = "auto")
public class Auto implements Serializable {
private static final long serialVersionUID = -4601105083604023376L;
#Id
#GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY )
#Column(name = "id")
private Long id;
#Column(name = "expediente_1")
private String expediente1;
#Column(name = "expediente_2")
private String expediente2;
#Column(name = "expediente_3")
private String expediente3;
#Column(name = "expediente_4")
private String expediente4;
#Column(name = "expediente_5")
private String expediente5;
#RestResource(exported = false)
#ManyToOne(cascade = CascadeType.MERGE, fetch= FetchType.EAGER)
#JoinColumn(name = "tipo_documento", referencedColumnName = "id")
private TipoDocumento tipoDocumento;
#Column(name = "numero_documento")
private Integer numeroDocumento;
#Column(name = "auto")
private String auto;
#Column(name = "patente")
private String patente;
#Column(name = "fecha_simbolo")
private Date fechaSimbolo;
#Column(name = "fecha_disposicion")
private Date fechaDisposicion;
#Column(name = "nro_disposicion")
private Integer nroDisposicion;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public TipoDocumento getTipoDocumento() {
return tipoDocumento;
}
public void setTipoDocumento(TipoDocumento tipoDocumento) {
this.tipoDocumento = tipoDocumento;
}
public Integer getNumeroDocumento() {
return numeroDocumento;
}
public void setNumeroDocumento(Integer numeroDocumento) {
this.numeroDocumento = numeroDocumento;
}
public String getExpediente1() {
return expediente1;
}
public void setExpediente1(String expediente1) {
this.expediente1 = expediente1;
}
public String getExpediente2() {
return expediente2;
}
public void setExpediente2(String expediente2) {
this.expediente2 = expediente2;
}
public String getExpediente3() {
return expediente3;
}
public void setExpediente3(String expediente3) {
this.expediente3 = expediente3;
}
public String getExpediente4() {
return expediente4;
}
public void setExpediente4(String expediente4) {
this.expediente4 = expediente4;
}
public String getExpediente5() {
return expediente5;
}
public void setExpediente5(String expediente5) {
this.expediente5 = expediente5;
}
public String getAuto() {
return auto;
}
public void setAuto(String auto) {
this.auto = auto;
}
public String getPatente() {
return patente;
}
public void setPatente(String patente) {
this.patente = patente;
}
public Date getFechaSimbolo() {
return fechaSimbolo;
}
public void setFechaSimbolo(Date fechaSimbolo) {
this.fechaSimbolo = fechaSimbolo;
}
public Date getFechaDisposicion() {
return fechaDisposicion;
}
public void setFechaDisposicion(Date fechaDisposicion) {
this.fechaDisposicion = fechaDisposicion;
}
public Integer getNroDisposicion() {
return nroDisposicion;
}
public void setNroDisposicion(Integer nroDisposicion) {
this.nroDisposicion = nroDisposicion;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.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;
Auto other = (Auto) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
I have two classes which has a relationship between them. These are
com.edfx.adb.persist.Activity:
package com.edfx.adb.persist.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.NaturalId;
#javax.persistence.Entity
#Table(name = "ACTIVITY")
public class Activity extends Entity {
#Transient
private static final long serialVersionUID = 4741665931936809028L;
private String activityId;
private String activityName;
private String activityDescription;
private Customer customer;
private ActivityType activityType;
private boolean active;
private Double mandays;
private Double price;
private String manager;
private List<Participation> participations;
public Activity() {
super();
}
#NaturalId
#Column(name = "ACTIVITY_ID", nullable = false)
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
#Lob
#Column(name = "ACTIVITY_NAME", nullable = false)
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
#Lob
#Column(name = "ACTIVITY_DESCRIPTION", nullable = false)
public String getActivityDescription() {
return activityDescription;
}
public void setActivityDescription(String activityDescription) {
this.activityDescription = activityDescription;
}
#ManyToOne
#JoinColumn(name = "CUSTOMER_ID", nullable = false)
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
#ManyToOne
#JoinColumn(name = "ACTIVITY_TYPE_ID", nullable = false)
public ActivityType getActivityType() {
return activityType;
}
public void setActivityType(ActivityType activityType) {
this.activityType = activityType;
}
#Column(name = "ACTIVE", nullable = false)
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
#Column(name = "MANDAYS")
public Double getMandays() {
return mandays;
}
public void setMandays(Double mandays) {
this.mandays = mandays;
}
#Column(name = "PRICE")
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
#Column(name = "CUSTOMER_SIDE_MANAGER")
public String getManager() {
return manager;
}
public void setManager(String manager) {
this.manager = manager;
}
#OneToMany(mappedBy = "activity", fetch = FetchType.LAZY)
#Cascade(CascadeType.SAVE_UPDATE)
public List<Participation> getParticipations() {
return participations;
}
public void setParticipations(List<Participation> participations) {
this.participations = participations;
}
}
com.edfx.adb.persist.ActivityType:
package com.edfx.adb.persist.entity;
import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
#javax.persistence.Entity
#Table(name = "ACTIVITY_TYPE")
public class ActivityType extends Entity {
#Transient
private static final long serialVersionUID = 2322745769010162801L;
private String parent;
private String name;
private String activityId;
public ActivityType() {
}
#Column(name = "PARENT", nullable = false)
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
#Column(name = "NAME", nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "ACTIVITY_ID", nullable = false)
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
}
Both of them extends com.edfx.adb.persist.entity.Entity:
package com.edfx.adb.persist.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.persistence.Version;
import org.hibernate.proxy.HibernateProxyHelper;
#MappedSuperclass
public class Entity implements Serializable {
#Transient
private static final long serialVersionUID = 7470288121057059283L;
private Long id;
private Date createTimestamp;
private Date lastUpdateTimestamp;
private Long version;
public Entity() {
super();
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID", updatable = false, nullable = false, unique = true)
public Long getId() {
return id;
}
#SuppressWarnings("unused")
private void setId(Long id) {
this.id = id;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CREATE_TIMESTAMP")
public Date getCreateTimestamp() {
return createTimestamp;
}
public void setCreateTimestamp(Date createTimestamp) {
this.createTimestamp = createTimestamp;
}
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "LAST_UPDATE_TIMESTAMP")
public Date getLastUpdateTimestamp() {
return lastUpdateTimestamp;
}
public void setLastUpdateTimestamp(Date lastUpdateTimestamp) {
this.lastUpdateTimestamp = lastUpdateTimestamp;
}
#Version
#Column(name = "VERSION")
public Long getVersion() {
return version;
}
#SuppressWarnings("unused")
private void setVersion(Long version) {
this.version = version;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
return prime * result + ((getId() == null) ? super.hashCode() : getId().hashCode());
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!getClass().equals(HibernateProxyHelper.getClassWithoutInitializingProxy(obj))) {
return false;
}
final Entity other = (Entity) obj;
if (getId() != other.getId()) {
if (getId() == null) {
return false;
}
if (!getId().equals(other.getId())) {
return false;
}
}
return true;
}
}
Now I am using Primefaces datatable to show a List<Activity> in which I have filtering on the field name of ActivityType. ActivityType is associated with Activity by #ManyToOne relationship.
For filtering the List<Activity> I am using:
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);
criteria.createCriteria("activityType").add(Restrictions.like("name", value.toString(), MatchMode.START));
I am getting:
null: org.hibernate.QueryException: duplicate association path: activityType
at org.hibernate.loader.criteria.CriteriaQueryTranslator.createAssociationPathCriteriaMap(CriteriaQueryTranslator.java:172) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.loader.criteria.CriteriaQueryTranslator.<init>(CriteriaQueryTranslator.java:111) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:84) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1602) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374) [hibernate-core-4.1.8.Final.jar:4.1.8.Final]
at com.edfx.adb.dao.ActivityDao.loadActivities(ActivityDao.java:54) [classes:]
at com.edfx.adb.service.ActivityService.loadActivities(ActivityService.java:101) [classes:]
This error is not showing always and never after the first load. After filtering the table for 5-6 time, I am having this error.
I am worried that if the mapping and the criteria is right or not. Any suggestion would be very helpful.
I think you need to provide an alias, so you should change your code this way:
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);
criteria.createCriteria("activityType", "at")
.add(
Restrictions.like("at.name", value.toString(), MatchMode.START));