My table VENDORBRANCH has composite keys: "vendorCode" and "vendorBranchCode" which I have defined using the #Id annotation and using #IdClass. The field "vendorCode" is referenced as a foreign key in VENDORCRTERMS class. I'm using postgresql db.
Right now my sql query in the service implimentation looks like this but i want to include composite keys in the query:
Query<?> query = session.createQuery("from VENDORBRANCH where vendorCode = ?");
query.setParameter(0, mf01_vendorCode);
I'm very new to hibernate so tried a few options for the select query but I'm not sure if it's correct to do it this way. So, what would be the best select statement to use for a composite key??
VENDORBRANCH class:
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.parkson.poMain.backend.data.VENDORBRANCH.VBpk;
#SuppressWarnings("serial")
#Entity
#IdClass(VBpk.class)
public class VENDORBRANCH implements Serializable {
#Id
private String vendorCode;
#Id
private String vendorBranchCode;
//getters and setters
// inner class defined for primary key(composite keys)
public static class VBpk implements Serializable {
protected String vendorCode;
protected String vendorBranchCode;
public String getvendorCode() {
return vendorCode;
}
public void vendorCode(String vendorCode) {
this.vendorCode = vendorCode;
}
public String vendorBranchCode() {
return vendorBranchCode;
}
public void vendorBranchCode(String vendorBranchCode) {
this.vendorBranchCode = vendorBranchCode;
}
public VBpk(){}
public VBpk(String vendorCode,String vendorBranchCode){
this.vendorCode = vendorCode;
this.vendorBranchCode = vendorBranchCode;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((vendorBranchCode == null) ? 0 : vendorBranchCode.hashCode());
result = prime * result + ((vendorCode == null) ? 0 : vendorCode.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;
VBpk other = (VBpk) obj;
if (vendorBranchCode == null) {
if (other.vendorBranchCode != null)
return false;
} else if (!vendorBranchCode.equals(other.vendorBranchCode))
return false;
if (vendorCode == null) {
if (other.vendorCode != null)
return false;
} else if (!vendorCode.equals(other.vendorCode))
return false;
return true;
}
}
}
My other class: VENDORCRTERMS
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#SuppressWarnings("serial")
#Entity
public class VENDORCRTERMS implements Serializable {
#Id
private String vcrId ;
//This is the foreign key referenced from **VENDORBRANCH class**
#ManyToOne
#JoinColumns( {
#JoinColumn(name="vendorcode", nullable = false),
#JoinColumn(name="vendorBranchCode", nullable = false)} )
private VENDORBRANCH vendorbranch_vendorcode = new VENDORBRANCH();
// foreign key referenced from a different class
#ManyToOne
#JoinColumn(name= "creditterms_credittermscode" , nullable = false)
private CREDITTERMS creditterms_credittermscode = new CREDITTERMS();
//getters and setters
}
VENDORBRANCH has defined a composite primary key but in VENDORCRTERMS you only use on #JoinColumn for the reference. This is how the mapping should look like in your case:
#ManyToOne
#JoinColumns( {
#JoinColumn(name="vendorCode", referencedColumnName="vendorCode"),
#JoinColumn(name="vendorBranchCode", referencedColumnName="vendorBranchCode")
} )
private VENDORBRANCH vendorbranch_vendorcode
The reason is: VENDORCRTERMS class is confused because he observed that there are two #ids in VENDORBRANCH. I have a solution for you. What if you make the vendorCode and vendorBranchCode as unique key as well as keeping only one primary key.
#Id
private String vendorCode;
I think this will satisfy your demand.
Related
This question already has an answer here:
How to fix "java.sql.SQLException: Column 'id' not found." error in Spring Boot
(1 answer)
Closed 2 years ago.
I get an
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "PRICEAFTERDISCOUNT" not found; SQL statement:
This is my Item class
package com.example.demo.model.persistence;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
#Entity
#Data
#Table(name = "item")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#JsonProperty
private Long id;
#Column(nullable = false)
#JsonProperty
private String name;
#Column(nullable = false)
#JsonProperty
private BigDecimal price;
#Column(nullable = false)
#JsonProperty
private BigDecimal priceAfterDiscount;
#Column(nullable = false)
#JsonProperty
private String description;
#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;
Item other = (Item) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
And this is my data.sql file
insert into item (name, price, priceAfterDiscount, description) values ('Travel Card Holder', 9.25, 0, 'A holder for your travel card');
insert into item (name, price, priceAfterDiscount, description) values ('Personalised cufflinks', 45.00, 0, 'Cufflings with your initials');
insert into item (name, price, priceAfterDiscount, description) values ('Kids T-shirt', 19.95, 0, 'A T-shirt with dinosaurs')
As far as I can tell, I have added the priceAfterDiscount into my insert statement so I do not
understand where the error comes from, or why it occurs in the first place. Please help!
I have added the priceAfterDiscount field in the Item class. And annotated the same way as the rest of the fields. Also, the syntax looks correct to me
The exception means your database table item does not contain a column named PRICEAFTERDISCOUNT. Check database column name and add it over field annotation argument this way #Column(name="database_column_name", nullable = false).
data.sql statements have to contain the right column names also.
I'm new to Hibernate/JPA. I wrote a simple demo project to start understanding the technology. I have this problem: everything works fine but filtering the persistence object on table primary key field. Every other field can be used to filter the objects without any problem even when I use multiple filters.
This is the simple demo code I wrote:
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<BaRoles> criteriaQuery = criteriaBuilder.createQuery(BaRoles.class);
Root<BaRoles> root = criteriaQuery.from(BaRoles.class);
criteriaQuery.select(root).where(criteriaBuilder.equal(root.get("rocode"), 78));
//criteriaQuery.select(root).where(criteriaBuilder.equal(root.get("rodescri"), "xxxxxxxx")); <-- Works fine
Query<BaRoles> query = session.createQuery(criteriaQuery);
List<BaRoles> roles = query.getResultList(); // <-- Returns nothing filtering rocode, correctly returns obejcts when filtering rodescri
for (int roleCounter = 0; roleCounter < roles.size(); roleCounter++) {
BaRoles role = (BaRoles) roles.get(roleCounter);
}
This is the complete stack trace:
java.lang.NullPointerException
at org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation.from(BasicValuedPathInterpretation.java:50)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitBasicValuedPath(BaseSqmToSqlAstConverter.java:747)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitBasicValuedPath(BaseSqmToSqlAstConverter.java:158)
at org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath.accept(SqmBasicValuedSimplePath.java:87)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitComparisonPredicate(BaseSqmToSqlAstConverter.java:1545)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitComparisonPredicate(BaseSqmToSqlAstConverter.java:158)
at org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate.accept(SqmComparisonPredicate.java:67)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:364)
at org.hibernate.query.sqm.sql.internal.StandardSqmSelectTranslator.visitSelectStatement(StandardSqmSelectTranslator.java:169)
at org.hibernate.query.sqm.sql.internal.StandardSqmSelectTranslator.translate(StandardSqmSelectTranslator.java:111)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:224)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.resolveCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:191)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:153)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:413)
at org.hibernate.query.spi.AbstractQuery.list(AbstractQuery.java:1356)
at org.hibernate.query.Query.getResultList(Query.java:136)
at com.xxxx.xxxxx.mavenproject1.BaRoleManager.readWithFilter(BaRoleManager.java:153)
at com.xxxx.xxxxx.mavenproject1.BaRoleManager.main(BaRoleManager.java:201)
And this is the BaRoles class (Generate with JPA):
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "ba_roles")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "BaRoles.findAll", query = "SELECT b FROM BaRoles b"),
#NamedQuery(name = "BaRoles.findByRocode", query = "SELECT b FROM BaRoles b WHERE b.rocode = :rocode"),
#NamedQuery(name = "BaRoles.findByRodescri", query = "SELECT b FROM BaRoles b WHERE b.rodescri = :rodescri"),
#NamedQuery(name = "BaRoles.findByCpccchk", query = "SELECT b FROM BaRoles b WHERE b.cpccchk = :cpccchk"),
#NamedQuery(name = "BaRoles.findByRodescriEng", query = "SELECT b FROM BaRoles b WHERE b.rodescriEng = :rodescriEng")
})
public class BaRoles implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
//#TableGenerator(name = "roleGenerator", table = "cpwarn", allocationSize = 1, pkColumnName = "tablecode", valueColumnName = "autonum", pkColumnValue = "prog\\ba_roles", schema="dbo", initialValue = 0)
#TableGenerator(name = "roleGenerator", table = "cpwarn", allocationSize = 1, pkColumnName = "tablecode", valueColumnName = "autonum", pkColumnValue = "prog\\ba_roles")
#GeneratedValue(strategy = GenerationType.TABLE, generator = "roleGenerator")
#Column(name = "ROCODE", updatable = false, nullable = false)
private Integer rocode;
#Column(name = "RODESCRI")
private String rodescri;
#Column(name = "cpccchk")
private String cpccchk;
#Column(name = "RODESCRI_ENG")
private String rodescriEng;
public BaRoles() {
}
public BaRoles(Integer rocode) {
this.rocode = rocode;
}
public Integer getRocode() {
return rocode;
}
public void setRocode(Integer rocode) {
this.rocode = rocode;
}
public String getRodescri() {
return rodescri;
}
public void setRodescri(String rodescri) {
this.rodescri = rodescri;
}
public String getCpccchk() {
return cpccchk;
}
public void setCpccchk(String cpccchk) {
this.cpccchk = cpccchk;
}
public String getRodescriEng() {
return rodescriEng;
}
public void setRodescriEng(String rodescriEng) {
this.rodescriEng = rodescriEng;
}
#Override
public int hashCode() {
int hash = 0;
hash += (rocode != null ? rocode.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 BaRoles)) {
return false;
}
BaRoles other = (BaRoles) object;
if ((this.rocode == null && other.rocode != null) || (this.rocode != null && !this.rocode.equals(other.rocode))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.xxxx.xxxx.mavenproject1.BaRoles[ rocode=" + rocode + " ]";
}
}
Solved! Reverted Hibernate version from 6.0.0 alpha 4 to 5.4.12 final (Maven repository). Everything works as expected. Thank you everyone for your time and effort.
My Child objects are getting detached once after the parent object is persisted. on returning the parent object to view ,my child objects are null. To resolve this I'm fetching the object again from database to process in the view.
//Pseudocode
Parent Entity
class Donor{
#ManyToOne(fetch = FetchType.EAGER)
private PreferredLanguage preferredLanguage;
}
Child Entity
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package model.preferredlanguage;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
*
* #author srikanth
*/
#Entity
public class PreferredLanguage {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, insertable=false, updatable=false)
private Long id;
#Column(length=20)
private String preferredLanguage;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPreferredLanguage() {
return preferredLanguage;
}
public void setPreferredLanguage(String preferredLanguage) {
this.preferredLanguage = preferredLanguage;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.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 PreferredLanguage)) {
return false;
}
PreferredLanguage other = (PreferredLanguage) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
Crntroller AddDonor Method
savedDonor = donorRepository.addDonor(donor);
Repository Method
public Donor addDonor(Donor donor) {
updateDonorAutomaticFields(donor);
em.persist(donor);
em.flush();
return donor;
}
Can you please provide code snippets,
My guess, your child objects may be of FetchType FetchType.LAZY
I want to use the PostgreSQL uuid type for objects' primary keys.
For that I've created a converter (implementing the Converter interface).
Bellow is the relevant code:
#Override
public void initialize(DatabaseMapping mapping, Session session) {
final DatabaseField field;
if (mapping instanceof DirectCollectionMapping) {
field = ((DirectCollectionMapping) mapping).getDirectField();
} else {
field = mapping.getField();
}
field.setSqlType(Types.OTHER);
field.setTypeName("uuid");
field.setColumnDefinition("UUID");
}
Then I've annotated the relevant entity X with the bellow annotations:
#Converter(name="uuidConverter",converterCalss=UUIDConverter.class)
#Convert("uuidConverter")
#Id
public UUID getId()
{
return id;
}
The problem is that I have another class (Y) which has the following definition:
#ManyToOne(targetEntity = X.class)
#JoinColumn(name = "x_id")
public X getX();
Although EclipseLink created the tables as expected it sends a string to the database when trying to insert objects of type Y.
Postgres returns the following error message:
column "id" is of type uuid but expression is of type character varying at character
Any solutions / work around will be appreciated.
I had the same issue with EclipseLink JPA + Postgresql + UUID as primary key.
To solve it, I've merged codes from Github and below link:
https://forums.oracle.com/forums/thread.jspa?messageID=4584157
The below code for UUIDConverter worked for me, though the code surely isn't the best.
public void initialize(DatabaseMapping ARGMapping, Session ARGSession)
{
final DatabaseField Field;
if (ARGMapping instanceof DirectCollectionMapping)
{
Field = ((DirectCollectionMapping) ARGMapping).getDirectField();
}
else
{
Field = ARGMapping.getField();
}
Field.setSqlType(Types.OTHER);
Field.setTypeName("uuid");
Field.setColumnDefinition("UUID");
for (DatabaseMapping m : ARGMapping.getDescriptor().getMappings())
{
assert OneToOneMapping.class.isAssignableFrom(ManyToOneMapping.class);
if (m instanceof OneToOneMapping)
{
for (DatabaseField field : ((OneToOneMapping) m).getForeignKeyFields())
{
field.setSqlType(Types.OTHER);
field.setColumnDefinition("UUID");
field.setTypeName("uuid");
}
}
}
}
I had some issues with EclipseLink JPA 2.1 + Postgresql + UUID as primary key but I find out different solution. I adopted AttributeConverter but I faced a problem with EclipseLink implementation that I resolved with this code:
#javax.persistence.Converter(autoApply = true)
public class PostgresUuidConverter implements AttributeConverter<UUID, Object> {
#Override
public Object convertToDatabaseColumn(UUID uuid) {
PostgresUuid object = new PostgresUuid();
object.setType("uuid");
try {
if (uuid == null) {
object.setValue(null);
} else {
object.setValue(uuid.toString());
}
} catch (SQLException e) {
throw new IllegalArgumentException("Error when creating Postgres uuid", e);
}
return object;
}
#Override
public UUID convertToEntityAttribute(Object dbData) {
if (dbData instanceof String) {
return UUID.fromString(dbData.toString());
} else {
return (UUID) dbData;
}
}
}
public class PostgresUuid extends PGobject implements Comparable<Object> {
private static final long serialVersionUID = 1L;
#Override
public int compareTo(Object arg0) {
return 0;
}
}
As I exaplined in detail in this post http://blog-ungarida.rhcloud.com/persisting-uuid-in-postgresql-using-jpa-eclipselink/
Try checking what the fieldClassification of the mapping is in the initialize method. It might be getting String.class somehow, try setting it to Object.class.
or, field.setType(Object.class)
It seems there is a bug/incompatibility between EclipseLink and PostgresQL. If you just use UUID for primary keys you should be okay. But if you have a nullable UUID column, and you try to store null in it, you will get the reported error:
column "whatever" is of type uuid but expression is of type character varying
See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=538138 (log in and vote for it if you have the time!)
That bug report proved very useful to me. Specifically the link to the forum thread at:
https://www.eclipse.org/forums/index.php?t=msg&th=1073632&goto=1719530&#msg_1719530
I tried all sorts of solutions from here on SO, and elsewhere on the web. The only one that seemed to work for me was the one posted by David Wheeler there. Specifically, creating a cast from character varying to uuid in the database.
Note that you have to be user postgres to create the cast:
$ sudo su - postgres
$ psql <your database name>
# drop cast if exists (character varying as uuid);
# create or replace function uuid(_text character varying) returns uuid language sql as 'select uuid_in(_text::cstring)';
# create cast (character varying as uuid) with function uuid(character varying) as assignment;
For completeness here is the rest of what I use (in case it helps)
All my entities (that have a UUID primary key) extend a base class called EntityBase:
package com.example.entity;
import java.io.Serializable;
import java.util.UUID;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.Converter;
import com.example.converter.UUIDTypeConverter;
#MappedSuperclass
#Converter(name="uuidConverter", converterClass=UUIDTypeConverter.class)
public class EntityBase implements Serializable, Cloneable
{
private static final long serialVersionUID = 1L;
#Id
#Convert("uuidConverter")
private UUID id;
public EntityBase() {
this.id = UUID.randomUUID();
}
#Override
public int hashCode() {
return id.hashCode();
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof EntityBase)) {
return false;
}
EntityBase other = (EntityBase) obj;
return getId().equals(other.getId());
}
public UUID getId()
{
return this.id;
}
public void setId(UUID id)
{
this.id = id;
}
}
The UUID converter class looks like this:
package com.example.converter;
import java.sql.Types;
import java.util.UUID;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
public class UUIDTypeConverter implements Converter
{
#Override
public UUID convertObjectValueToDataValue(Object objectValue, Session session)
{
return (UUID) objectValue;
}
#Override
public UUID convertDataValueToObjectValue(Object dataValue, Session session)
{
return (UUID) dataValue;
}
#Override
public boolean isMutable()
{
return true;
}
#Override
public void initialize(DatabaseMapping mapping, Session session)
{
DatabaseField field = mapping.getField();
field.setSqlType(Types.OTHER);
field.setTypeName("java.util.UUID");
field.setColumnDefinition("UUID");
}
}
If you have entities that have UUID columns that are not primary keys, you can annotate them as follows:
import org.eclipse.persistence.annotations.Convert
import org.eclipse.persistence.annotations.Converter;
#Entity
#Converter(name="uuidConverter", converterClass=UUIDTypeConverter.class)
public class BillingEvent extends EntityBase
{
#Convert("uuidConverter")
private UUID entityId;
}
Note that if that entity has other columns that use the standard javax.persistence.convert annotation, you'll need to differentiate the two Convert annotations to avoid a compile error.
For example:
import javax.persistence.Convert;
import org.eclipse.persistence.annotations.Converter;
#Entity
#Converter(name="uuidConverter", converterClass=UUIDTypeConverter.class)
public class BillingEvent extends EntityBase
{
#org.eclipse.persistence.annotations.Convert("uuidConverter")
private UUID entityId;
#Convert(converter = JSR310InstantTypeConverter.class)
private Instant createdOn;
}
I hope this saves others some time. Good luck!
Universal UUIDConverter for EclipseLink (not only PostgreSQL)
Code:
import java.nio.ByteBuffer;
import java.util.UUID;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
public class UUIDConverter implements Converter {
private Boolean isUUIDasByteArray = true;
#Override
public Object convertObjectValueToDataValue(Object objectValue,
Session session) {
if (isUUIDasByteArray) {
UUID uuid = (UUID)objectValue;
if (uuid == null) return null;
byte[] buffer = new byte[16];
ByteBuffer bb = ByteBuffer.wrap(buffer);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return buffer;
}
return objectValue;
}
#Override
public UUID convertDataValueToObjectValue(Object dataValue,
Session session) {
if (isUUIDasByteArray) {
byte[] bytes = (byte[])dataValue;
if (bytes == null) return null;
ByteBuffer bb = ByteBuffer.wrap(bytes);
long high = bb.getLong();
long low = bb.getLong();
return new UUID(high, low);
}
return (UUID) dataValue;
}
#Override
public boolean isMutable() {
return true;
}
#Override
public void initialize(DatabaseMapping mapping, Session session) {
final DatabaseField field;
if (mapping instanceof DirectCollectionMapping) {
// handle #ElementCollection...
field = ((DirectCollectionMapping) mapping).getDirectField();
} else {
field = mapping.getField();
}
if (session != null && session.getLogin()!= null && session.getLogin().getPlatform() != null) {
String platform = session.getLogin().getPlatform().getClass().getSimpleName();
if (platform.equals("PostgreSQLPlatform")) {
field.setSqlType(java.sql.Types.OTHER);
field.setTypeName("java.util.UUID");
field.setColumnDefinition("UUID");
isUUIDasByteArray = false;
} else if (platform.equals("H2Platform")) {
field.setColumnDefinition("UUID");
} else if (platform.equals("OraclePlatform")) {
field.setColumnDefinition("RAW(16)");
} else if (platform.equals("MySQLPlatform")) {
field.setColumnDefinition("BINARY(16)");
} else if (platform.equals("SQLServerPlatform")) {
field.setColumnDefinition("UNIQUEIDENTIFIER");
}
}
}
}
You don't need a converted. Use this column definition in the entity. You need to register the uuid extension first. This works with Postgres 10 and Wildfly 10.1
#Column(name = "UUID", nullable=false, insertable = false, columnDefinition="uuid DEFAULT uuid_generate_v4()")
private String uuid;
Using JPA, and Hibernate as the provideer, I have a class defined like:
#Entity
#Table(name="partyrole")
public class PartyRole extends BaseDateRangeModel {
private static final long serialVersionUID = 1L;
private Party roleFor;
public void setRoleFor(Party roleFor) {
this.roleFor = roleFor;
}
#ManyToOne
public Party getRoleFor() {
return roleFor;
}
}
And I get the error in title of the question. I've tried adding public void setType(Object type) but that doesn't work either. The persistence.xml file is normal.
There are two classes that reference this one, but neither of them attempts to invoke setType either. I'd apprecaite any help!!!!
This happens at deployment time. The stack trace is at the bottom.
The Parent Class:
package com.nsfw.bmp.common.jpa;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotNull;
/**
* Several models are date range sensitive, this base class provides that basic
* functionality.
*
* #author jim
*
*/
#MappedSuperclass
public abstract class BaseDateRangeModel extends BasePersistentModel {
private static final long serialVersionUID = 1L;
private Date from;
private Date thru;
/**
* Determines if a model is active. A model is active if now is after or
* equal to from , and thru is either null, or after now, or equal to now.
*/
#Transient
public boolean isActive() {
Date now = new Date();
boolean afterFrom = from.before(now) || from.equals(now);
boolean beforeThru = thru == null || thru.after(now)
|| thru.equals(now);
return afterFrom && beforeThru;
}
#AssertTrue(message = "Dates are not valid the thru date must be empty, or after the fromdate.")
public boolean areDatesValid() {
if (thru == null) {
return true;
} else {
return thru.after(from);
}
}
#Temporal(TemporalType.TIMESTAMP)
#NotNull
#Column(name = "fromDate")
public Date getFrom() {
return from;
}
public void setFrom(Date from) {
this.from = from;
}
#Temporal(TemporalType.TIMESTAMP)
public Date getThru() {
return thru;
}
public void setThru(Date thru) {
this.thru = thru;
}
}
Its parent:
package com.nsfw.bmp.common.jpa;
import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
#MappedSuperclass
public abstract class BasePersistentModel implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
protected Long id;
protected Long version = 0l;
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BasePersistentModel other = (BasePersistentModel) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
#Id
#GeneratedValue
public Long getId() {
return id;
}
#Version
public Long getVersion() {
return version;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
public void setId(Long id) {
this.id = id;
}
public void setVersion(Long version) {
this.version = version;
}
}
The Party class is fairly large, with a lot of mappings. This is the one asked for:
/**
* #return the actingAs
*/
#OneToMany(mappedBy="roleFor", targetEntity=com.nsfw.bmp.party.entity.association.PartyRole.class)
#OrderBy("from")
public List<PartyRole> getActingAs() {
return actingAs;
}
Here's the stack trace:
Caused by: org.hibernate.PropertyNotFoundException: Could not find a setter for property type in class com.nsfw.bmp.party.entity.association.PartyRole
at org.hibernate.property.BasicPropertyAccessor.createSetter(BasicPropertyAccessor.java:240)
at org.hibernate.property.BasicPropertyAccessor.getSetter(BasicPropertyAccessor.java:233)
at org.hibernate.mapping.Property.getSetter(Property.java:299)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertySetter(PojoEntityTuplizer.java:272)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:149)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:76)
at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:325)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:457)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:131)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
Can you post your party class? I have a suspicion that this has to do with your manytoone mapping. Is there a type column in the partyRole table?
You problem might be linked to the BaseDateRangeModel class, because PartyRole extends it.
can you show us that class?
If you're getting this during startup, it means you have a class somewhere referencing PartyRole via inverse relationship, e.g. something along the lines of
#OneToMany(targetEntity=PartyRole.class, inverse=true")
in some other entity. Set hibernate logging level to DEBUG - it should help you to narrow the problem.