#SqlResultSetMapping with #Embedded - java

I hava a problem with mapping embedded fields in Hibernate.
This is the code:
#Entity
#Table(name="CAR")
#SqlResultSetMapping(name = "carMapping",
entities = {
#EntityResult(entityClass = Car.class,
fields = {
#FieldResult(name = "id", column = "ID"),
#FieldResult(name = "producer", column = "PRODUCER"),
#FieldResult(name = "model", column = "MODEL"),
#FieldResult(name="bookNumber",column="SERVICE_BOOK_NUMBER"),
#FieldResult(name="owner", column="SERVICE_BOOK_OWNER")
}
)})
public class Car {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="ID")
private Long id;
#Column(name="PRODUCER")
private String producer;
#Column(name="MODEL")
private String model;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="bookNumber", column=#Column(name="SERVICE_BOOK_NUMBER")),
#AttributeOverride(name="owner", column=#Column(name="SERVICE_BOOK_OWNER")),
})
private ServiceBook serviceBook;
When I try to retrive a Car I get the following error:
javax.ejb.EJBTransactionRolledbackException: The transaction has been marked rollback only
because the bean encountered a non-application exception :javax.persistence.PersistenceException :
org.hibernate.exception.SQLGrammarException: Column 'SERVICE4_0_0_' not found
My question is: is it possible to use #SqlResultSetMapping and #Embedded together?

Create a new #EntityResult to ServiceBook such as you did with Car.class. I usually do this to bind columns to the attributes.

Related

Invalid Identifier in Hibernate Filter defaultCondition when trying to access a field of one of it's subfields

I am working on setting up some entities for a project that I am working on. My issue is that I am getting an invalid identifier error on my hibernate filters. Below is a simplified example:
#Data
#Entity
#Table(name = "###")
public class C1 {
#OneToMany(mappedBy = "###")
#Filter(name = "C2.set1Filter")
private Set<C2> set1;
#OneToMany(mappedBy = "###")
#Filter(name = "C2.set2Filter")
private Set<C2> set2;
#OneToMany(mappedBy = "###")
#Filter(name = "C2.set3Filter")
private Set<C2> set3;
}
#Data
#Entity
#Table(name = "###")
#FilterDefs({
#FilterDef(
name = "set1Filter"
defaultCondition = "c3.value = 'One'"
),
#FilterDef(
name = "set2Filter"
defaultCondition = "c3.value = 'Two'"
),
#FilterDef(
name = "set3Filter"
defaultCondition = "c3.value = 'Three'"
)
})
public class C2 {
#ManyToOne
#JoinColumn(name = "ID")
C3 c3;
}
#Data
#Entity
#Table(name = "###")
public class C3 {
#Id
#Column(name = "ID")
private Long id;
#Column(name = "VALUE")
private String value;
}
When the filters are off, they don't run, and therefore I don't get an error. However, when they are on, I am getting an error saying that c3.value is an invalid identifier.
I am obviously doing something wrong here. Is it possible to get the above to work?
As it stated in the documentation:
The #Filter condition uses a SQL condition and not a JPQL filtering predicate.
So, you should use actual tables and columns names.
#Filter(
name="setFilter",
condition="{c3}.VALUE = :val",
aliases = {
#SqlFragmentAlias( alias = "c3", table= "C3_TABLE_NAME")
}
)
As it stated here:
When using the #Filter annotation and working with entities that are mapped onto multiple database tables, you will need to use the #SqlFragmentAlias annotation if the #Filter defines a condition that uses predicates across multiple tables.

HibernateException- identifier of an instance of Domain was altered from X to Y

I am getting an exception when I am updating Parent record in spring data jpa.
This is my code:
ParentEntity
#Entity
#Table(name = "CAMP")
#Getter
#Setter
public class Parent extends AbstractEntity {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tkeygenerator")
#GenericGenerator(name = "tkeygenerator", strategy = "com.custom.TKeyGenerator",
parameters = {#org.hibernate.annotations.Parameter(name = "sequence", value = "TKEY_SEQ")})
#Column(name = "TKEY", nullable = false)
private String id;
#ManyToOne
#JoinColumn(name = "SUB_CAT_TYPE_CODE", referencedColumnName = "SUB_CAT_TYPE_CODE")
private Child child;
#Column(name = "DATE")
#Basic
private LocalDate date;
}
Child Entity
#Entity
#Table(name = "SUB_CAT_TYPE")
#AttributeOverrides({
#AttributeOverride(name = "code",
column = #Column(name = "SUB_CAT_TYPE_CODE", length = 30)),
#AttributeOverride(name = "description",
column = #Column(name = "SUB_CAT_TYPE_DESC", length = 255))})
#EqualsAndHashCode(callSuper = true)
public class Child extends AbstractTypeDesc {}
TestCode
public Parent update(#PathVariable("id") String id, #Valid #RequestBody UpdateDto dto) {
Parent parentObj = parentRepository.findById(id);
mapper.map(dto, parentObj); // Dozer to map incoming dto to domain
childRepository.findByCode(dto.child().getCode())
.map(child -> {
parentObj.setChild(child);
return child;
});
return parentRepository.save(parentObj); //Exception occurs here
}
I am getting an exception while trying to update code variable of child entity in parent entity as fk. It says can't alter code from X to Y.
Any suggestion?
I figured out what went wrong in above code block for update operation.Although not much clear why its happening.Dozer mapping which maps dto to Domain was causing issue it was changing the value of child entity and then again when i was trying to set child entity through setter method It was causing "Id alter exception", Though i thats the same thing i dont know why it was taking it differently. below is the working Working code.
Test code should be like
public Parent update(#PathVariable("id") String id, #Valid #RequestBody UpdateDto dto) {
Parent parentObj = parentRepository.findById(id);
childRepository.findByCode(dto.child().getCode())
.map(child -> {
parentObj.setChild(child);
return child;
});
mapper.map(dto, parentObj); // Dozer dto to domain mapping was causing problem
return parentRepository.save(parentObj);
}

Error in Join on a relation ManyToOne. Using QueryDSL

I have problems using join with QUeryDSL. I'm trying to receive a list of "Clube" which has a ManyToOne relation with "Federacao".
Could someone help me?
Thanks.
The relation is between the classes below.
#Entity
#Table(name = "federacoes")
#SequenceGenerator(name = "idgen", sequenceName = "federacoes_id_federacao_seq", allocationSize = 1)
#AttributeOverride(name = "id", column = #Column(name = "id_federacao"))
public class Federacao extends AbstractEntity{
private String sigla;
private String uf;
private String nome;
...
}
#Entity
#Table(name = "clubes")
#SequenceGenerator(name = "idgen", sequenceName = "clubes_id_clube_seq", allocationSize = 1)
#AttributeOverride(name = "id", column = #Column(name = "id_clube"))
public class Clube extends AbstractEntity{
private Federacao federacao;
...
#ManyToOne
#JoinColumn(name = "id_federacao")
#Column(name = "federacao")
public Federacao getFederacao() {
return federacao;
}
...
}
I'm using QueryDSL and in the repository class which extends QueryDslRepositorySupport I'm doing this:
...
#PersistenceContext
private EntityManager em;
private static final QClube qClube = QClube.clube;
private static final QFederacao qFederacao = QFederacao.federacao;
#Override
public List<Clube> findAll(FilterClubeDTO filterClubeDTO) {
JPAQuery query = new JPAQuery(em);
return query.from(qClube)
.innerJoin(qFederacao).on(qClube.federacao.eq(qFederacao))
.orderBy(qClube.id.desc())
.list(qClube);
}
I'm receiving this exception:
2016-04-12 12:32:38.485 ERROR 2853 --- [ qtp36627152-15] o.h.hql.internal.ast.ErrorCounter : Path expected for join!
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select clube
from br.com.cbfm.core.models.Clube clube
inner join Federacao federacao with clube.federacao = federacao
order by clube.id desc]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [select clube
from br.com.cbfm.core.models.Clube clube
inner join Federacao federacao with clube.federacao = federacao
order by clube.id desc]
This should work as expected:
JPAQuery query = new JPAQuery(em);
return query.from(qClube)
.innerJoin(qClube.federacao, qFederacao)
.orderBy(qClube.id.desc())
.list(qClube);
The query provided by Meiko is right. I've downloaded your project and found some issues related with the relations of the models.
Don't use the following code,
#ManyToOne
#JoinColumn(name = "id_federacao")
#Column(name = "federacao")
public Federacao getFederacao() {
return federacao;
}
But use,
#ManyToOne
#JoinColumn(name = "federacao")
private Federacao federacao;
Use the name "federacao" instead "id_federacao" because the column you want to join is clubes.federacao and not clubes.id_federacao.
You can't use #Column with #ManyToOne.
That should solve you're problem. I've also modified some little things, but that shouldn't affect the code to work.
The problem was in my mapping. I just fixed it doing it:
Class Clube
#ManyToOne
#JoinColumn(name="id_federacao", nullable=false)
private Federacao federacao;
and Class Federacao
#OneToMany(mappedBy="federacao")
private Set<Clube> clubes;
I have now another problem that I'll post right now.
Thanks everyone.

Hibernate: Parameter index out of range (8 > number of parameters, which is 7)

Not a duplicate of this question Parameter index out of range (8 > number of parameters, which is 7)
My SaltTranDef entity class is
#Id
#Column(name="salt_id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer saltId;
#Column(name="tran_type")
private String transactionType;
#Column(name="user_id")
private String userId;
#Column(name="parent_system")
private String parentSystem;
#Column(name="parent_sys_ref_id")
private String parentSystemReference;
#Column(name="status")
private int status;
#OneToMany(mappedBy = "saltTranDef")
#Cascade({ org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private Set<SaltTranUser> saltTranUsers;
And the SaltTranUser entity class is
#Id
#Column(name="salt_id")
private Integer saltId;
#Id
#Column(name="salt_property")
private String saltProp;
#Column(name="salt_value")
private String saltValue;
#ManyToOne
#JoinColumn(name="salt_id")
private SaltTranDef saltTranDef;
Both the above entity classes extend a mappedSuperclass
#Column(name="cre_suid")
private String creatorId;
#Column(name="mod_suid")
private String modifiedId;
#Column(name="cre_date")
private Timestamp creationDate;
#Column(name="mod_date")
private Timestamp modificationDate;
When inserting from a JUnit:
#Test
public void testInsert(){
SaltTranDef std = new SaltTranDef();
SaltTranUser stu1 = new SaltTranUser();
SaltTranUser stu2 = new SaltTranUser();
SaltTranUser stu3 = new SaltTranUser();
Set<SaltTranUser> set1 = new HashSet<SaltTranUser>();
Transaction tx = session.beginTransaction();
std.setParentSystem("A");
std.setParentSystemReference("123");
std.setStatus(10);
std.setTransactionType("A");
std.setUserId("1234");
std.setCreationDate(new Timestamp(new Date().getTime()));
std.setCreatorId("1234");
session.persist(std);
// session.flush();
stu1.setCreationDate(new Timestamp(new Date().getTime()));
stu1.setCreatorId("1234");
stu1.setSaltProp("Fname");
stu1.setSaltValue("Swateek");
stu1.setSaltId(std.getSaltId());
stu2.setCreationDate(new Timestamp(new Date().getTime()));
stu2.setCreatorId("1234");
stu2.setSaltProp("Lname");
stu2.setSaltValue("Jena");
stu2.setSaltId(std.getSaltId());
stu3.setCreationDate(new Timestamp(new Date().getTime()));
stu3.setCreatorId("1234");
stu3.setSaltProp("Phone");
stu3.setSaltValue("9900056668");
stu3.setSaltId(std.getSaltId());
set1.add(stu1);
set1.add(stu2);
set1.add(stu3);
std.setSaltTranUsers(set1);
session.save(std);
tx.commit();
}
I get an error saying:
SEVERE: Parameter index out of range (8 > number of parameters, which is 7).
Mar 25, 2015 8:06:35 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: could not insert: [com.salt.entity.SaltTranUser]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
Caused by: java.sql.SQLException: Parameter index out of range (8 > number of parameters, which is 7).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
This kind of problem is almost always related to double column mapping. And indeed. We can see, that this mapping uses one column twice "salt_id":
the SaltTranUser entity class:
#Id
#Column(name="salt_id")
private Integer saltId;
...
#ManyToOne
#JoinColumn(name="salt_id")
private SaltTranDef saltTranDef;
And that is wrong. Hibernate is at the end inserting into one column twice, i.e. more arguments then columns in INSERT, UPDATE
Solution here would be mostlikely very simple - because the #ManyToOne seems to be wrong. I would expect some special column for reference like: SaltTranDef_id
I faced same issue when I was using the one-directional mapping (parent class containing child class, but child class doesn't keep the reference of parent class).
The mapping looked like
#OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval = true)
#JoinColumn(name="jobcard_id", nullable=false)
private List<JobServiceMapping> services;
I got the error Parameter index out of range.
Then I changed the annotations a bit and now it is working for me.
#OneToMany(mappedBy="jobcardId", cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval = true)
private List<JobServiceMapping> services;
In my case issue was with user_type field. It was defined as discriminator and as public property. It wasn't marked with #Column but somehow Hibernate anyway failed on this
#Entity
#Table(
name = "abstract_users",
indexes = {#Index(name = "idx__abstract_users__is_enabled", columnList = "is_enabled")}
)
#Access(AccessType.FIELD)
#Inheritance(strategy = InheritanceType.JOINED)
// #TODO: rename user_type to discriminator
#DiscriminatorColumn(name = "user_type", discriminatorType = DiscriminatorType.STRING, length = 10)
abstract public class AbstractUser extends CreateUpdateTimestampableBase
{
// #TODO: rename user_type to discriminator
public String user_type;
#Min(0)
#NotNull
#Column(precision = 19, scale = 2)
protected BigDecimal balance;
//...
}
In your entity, replace
#ManyToOne
#JoinColumn(name="salt_id")
private SaltTranDef saltTranDef;
by
#ManyToOne
#JoinColumn(name="salt_id", updatable = false, insertable = false)
private SaltTranDef saltTranDef;
it worked for me

Hibernate #Any annotation usage

I have one entity called Change where I need log changes in database like inserting, updating or deleting rows.
So my Change table contains some data and now I would like to add foreign key to record changes in another table, but I have different tables. For example I have Weather table, Group table,... So I have done some searching and I have found a little bit about #Any annotation. So I added some columns to my Change entity:
#Entity
#Table(name = "CHANGE")
public class Change {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "CHANGE_ID")
private int changeId;
...
#Any(metaColumn = #Column(name = "RECORD_TABLE"))
#AnyMetaDef(idType = "int", metaType = "string",
metaValues = {
#MetaValue(targetEntity = Weather.class, value = "WEATHER"),
#MetaValue(targetEntity = Group.class, value = "GROUP"),
...
})
#JoinColumn(name="recordID")
private Object record;
#ManyToOne
#JoinColumn(name = "USER_ID")
private User user;
public Object getRecord() {
return record;
}
public void setRecord(Object record) {
this.record = record;
}
...
And my stupid question is:
How can I insert data into database (like foreign ID and class name) and how could I retrieve them?
Please go through this Link
You should care about your entity relationship (1-1 or 1-M or M-M)

Categories

Resources