I have some classes in my java spring boot project. I use jpa and xampp for localhost. All the Entity classes work and create tables for every #Entity class. But this class does not work. Why?
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
public class Match {
#Id
private String matchId;
#Enumerated
private MatchType matchType;
}
Try this:
#AllArgsConstructor
#NoArgsConstructor
#Data
#Entity
#Table(name = "\"Match"\")
public class Match {
#Id
private String matchId;
#Enumerated
private MatchType matchType;
}
More general, if you set
hibernate.globally_quoted_identifiers=true
every identifier gets quoted.
Related
I'm trying to access an attribute in one of my entity classes: "products" that is a list:
#Entity
#Table(name = "TRANSACTION")
#Getter
#NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Transaction extends BaseTransaction {
...
#OneToMany(mappedBy="transaction)
private List<Product> products;
...
}
#Entity
#Table(name = "PRODUCT")
#Getter
#AllArgsConstructor
#NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Product {
....
#ManyToOne
#PrimaryKeyJoinColumn
#Getter
#NonNull
private Transaction transaction;
....
#Embedded
#AttributeOverrides({
#AttributeOverride(name = "name", column = #Column(name = "seller_name")),
#AttributeOverride(name = "country", column = #Column(name = "seller_country")) })
private NameAndCountry seller;
...
}
#Embeddable
#AllArgsConstructor
#Getter #Setter
#NoArgsConstructor(access = AccessLevel.PRIVATE)
public class NameAndCountry {
private String name;
private String country;
}
Given a string: "myName", and by using JPA criteria builder, I'm trying to retrieve the name of the seller of the transaction, and this is what have when I'm trying to build the predicate:
Join<Object, Object> transactionProductJoin = root.join("products");
Predicate predicate_ = criteriaBuilder.equal(transactionProductJoin.get("products").get("seller").get("name"), "myName");
However I'm facing an error which says:
Unable to locate Attribute with the the given name [products] on this ManagedType [work.my.domain.models.BaseTransaction]
Why is JPA criteria builder trying to retrieve the "products" attribute from the parent class of Transaction? What should be the correct way to construct the predicate?
Following is the example where we map Parent and Child entity classes using JPA Annotations.
#Entity
#Table(name = "Parent")
#Inheritance(strategy = InheritanceType.JOINED)
public class Parent {
// Getter and Setter methods
}
#Inheritance – Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.
#InheritanceType – Defines inheritance strategy options.
Single table per class hierarchy strategy: a single table hosts all the instances of a class hierarchy
Joined subclass strategy: one table per class and subclass is present and each table persist the properties specific to a given subclass. The state of the entity is then stored in its corresponding class table and all its superclasses
Table per class strategy: one table per concrete class and subclass is present and each table persist the properties of the class and its superclasses. The state of the entity is then stored entirely in the dedicated table for its class.
#Entity
#Table(name="Child")
public class Child extends Parent {
//Getter and Setter methods,
}
#Inheritance(strategy = InheritanceType.JOINED)
Should be added to the parent entity. (Depending on the InheritanceType required for your scenario.)
Check these links for reference:
Chapter 10. Inheritance mapping
5.1.6. Inheritance strategy
The issue is solved, the problem was in the construction of the predicate:
Wrong:
Predicate predicate_ = criteriaBuilder.equal(transactionProductJoin.get("products").get("seller").get("name"), "myName");
Correct:
Predicate predicate_ = criteriaBuilder.equal(transactionProductJoin.get("seller").get("name"), "myName");
I'm new to JPA and still learning
I have one doubt/problem related to JPA
and I'm too confused to find any solution can someone please let me know if I can do any workaround to get this done or point me to some documentation if it is possible.
My json structure:
{
"Action":"txn",
"Rec_count":"1",
"Page_count":"1",
"Records":
[
{
"Pan":"abcd",
"CRN":"cedf"},
{
"Pan":"1234",
"CRN":"sfdg"}
]
}
Now if I want to give #Id for the CRN field and store all the values i.e., action, rec_count, page_count, pan and CRN in the same table and iteration of the array (two rows in the above case),
can that be accomplished or there is no way to do that?
Because #Embeddable can be used to store everything in same table but you can't assign #id to the embeddable class.
The entity class
import lombok.*;
import javax.persistence.*;
import java.util.List;
#Table(name="GET_RECORDS")
#ToString
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Entity
public class entityClass{
private String Action;
private int Rec_cnt;
private String Page_count;
#OnetoMany
private List<Records> records;
}
And I tried creating a Records class as
import lombok.*;
import javax.persistence.*;
#ToString
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#embeddable
public class Records{
#Id
#NotNull
private String CRN;
#NotNull
private int PAN;
}
I'm getting the error onetomany attribute value type should not be embeddable
Please let me know if there is any way to do this ?
I am facing troubles with #Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) and autogenerated table Ids.
Here below is my model:
#Getter
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
#DiscriminatorColumn(name = "type")
#SuperBuilder
#NoArgsConstructor
public abstract class MenuEntity {
#Id
#EqualsAndHashCode.Include
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
//...
}
#Getter
#Entity
#Table(name = "tasting_menu")
#SuperBuilder
#NoArgsConstructor
public class TastingMenuEntity extends MenuEntity {
//...
}
#Getter
#Setter
#Entity
#Table(name = "simple_menu")
#SuperBuilder
#NoArgsConstructor
public class SimpleMenuEntity extends MenuEntity {
//...
}
In development process, I have defined a data.sql scripts which inserts test data into my H2 inmemory database. Those scripts will work fine only if I specify the ID value in the statement, in other case I get NULL not allowed for column "ID". Thus, I have to set the ID in the insert statement (the issue does not appear in other entities with no inheritance strategy and #GeneratedValue(strategy = GenerationType.IDENTITY)).
A new problem comes: when the application tries to insert a SimpleMenuEntity on execution time an exception is thrown: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.SIMPLE_MENU(ID) because the sequence is still value 1 even it already has some test data.
I have some questions so far.
1. Is my model right?
I have to use #Entity instead of #MappedSuperclass in my abstract class because it has #ManyToOne annotation.
ID property is common for all child tables, but I would like that each table has its own id sequence.
2. How should I handle the autogenerated ID for SQL INSERT statements?
I definitive need the test data in my application for development porpouse.
Problem
I have a Field in a MappedSuperClass which is anotated with #Column but the type of the field is not being determined by Hibernate.
Classes
#Getter
#Setter
#MappedSuperClass
public abstract class IdentifiableObject {
#Id
#GeneratedValue
private Integer id;
}
#Getter
#Setter
#MappedSuperClass
public abstract class EvaluationPeriodObject extends IdentifiableObject{
#Column
private Period period;
}
#Data
#Entity
#Table(name = "PERIOD")
public class Period extends IdentifiableObject {
#Column
private LocalDate start;
#Column
private LocalDate end;
}
#Data
#Entity
#Table(name = MY_CLASS, indexes = {
#Index(name = "FK_MY_CLASS_PERIOD", columnList = "PERIOD")
})
public class MyClass extends EvaluationPeriodObject {
#Column
private String description;
}
Stacktrace
Caused by: org.hibernate.MappingException: Could not determine type for: Period, at table: MY_CLASS, for columns: [org.hibernate.mapping.Column(period)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:455)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
at org.hibernate.mapping.Property.isValid(Property.java:226)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597)
at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:459)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
... 45 more
Additional Info
Hibernate Version: compile 'org.hibernate:hibernate-core:5.2.13.Final'
SpringBoot Version 2.0.0.RELEASE
If more Information is required, let me know.
I've been reading most post about this but form what I've read they mostly envolve people using annotations on 'Getters' and 'Fields', Since I'm using Lombok I don't have any Getters to put the annotations on so I believe this is not the problem I'm facing.
Please try to add AccessType.FIELD to getter and setter annotations #Getter(AccessType.FIELD).
I am using JPA query in spring , My subclass extends Baseclass whic contains an Id only and My subclass has all the variavles that is used by the JPA query given below:
Base Class:
#MappedSuperclass
#Table(name = "partcost")
#NoArgsConstructor
#AllArgsConstructor
#Data
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Pg6p0012_01PartCostBaseQueryModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
String part_no;
}
Subclass :
#Entity
#Table(name = "partcost")
#NoArgsConstructor
#AllArgsConstructor
#Data
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Pg6p0012_01PartCost1QueryModel extends Pg6p0012_01PartCostBaseQueryModel implements Serializable {
private static final long serialVersionUID = 1L;
private String stock_take_cost ;
private String cost_type ;
}
when I am hiting below JPA Query :
#Repository
#Transactional
public interface Pg6p0012_01PartcostRepository extends JpaRepository<Pg6p0012_01PartCostBaseQueryModel, String> {
#Query(value = "SELECT stock_take_cost,cost_type FROM partcost where part_no = :p_part_no", nativeQuery = true)
public List<Pg6p0012_01PartCost1QueryModel>getPartcost1Result(#Param("p_part_no") String p_part_no);
}
its throwing Error: No such column name
which is clear because query is returning only one column but Model has two columns .
How to tackle this ? please suggest.
You make part_no transient . It means that it is not persisted in the database.Therefore you are getting no such column name error. Remove #Transient from the base class which is above the part_no.
And also annotate your base class with
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
Hibernate supports the three basic inheritance mapping strategies:
table per class hierarchy
table per subclass
table per concrete class