Why bidirectional mapping fails with empty relationship - java

Following are my two related tables
public class VProduct{
#Id
#Column(name="product_id")
private Long productId;
#OneToMany(mappedBy="vProduct", fetch = FetchType.EAGER, cascade={CascadeType.REMOVE})
private Set<ProductPan> pans;
}
public class ProductPan {
#Id
#Column(name="product_pan_id")
private Long productPanId;
#Fetch(FetchMode.JOIN)
#ManyToOne(optional=true, fetch=FetchType.EAGER)
#JoinColumn(name="product_id", referencedColumnName = "product_id", insertable = false, updatable = false)
private VProduct vProduct;
}
I get the following exception when i try to query the VProduct tabel.
org.hibernate.exception.SQLGrammarException: ERROR: column pans0_.product_pan_id does not exist
What am i doing wrong here ? At the moment ProductPan table is empty. And its not guranteed to have any items for a VProduct. if thats the problem is there any annotation i can add to ignore that null data problem ?
This is the hibernate query and result
14:39:49,994 INFO [stdout] (http-localhost-127.0.0.1-8080-1) Hibernate: select pans0_.product_id as product3_101_1_, pans0_.product_pan_id as product1_1_, pans0_.product_pan_id as product1_71_0_, pans0_.pan_id as pan2_71_0_, pans0_.product_id as product3_71_0_ from product_pan pans0_ where pans0_.product_id=?
14:39:50,113 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-1) SQL Error: 0, SQLState: 42703
14:39:50,116 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-localhost-127.0.0.1-8080-1) ERROR: column pans0_.product_pan_id does not exist

Related

Hibernate mapping error while inserting child record

I have two entity class as below -
public class Parent {
#Id
private Integer parentId;
private String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children;
}
public class Child {
#Id
private Integer childId;
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "parentId", insertable = false, updatable = true, nullable = false)
private Parent parent;
}
#RestController
public class ParentController {
#Autowired
private ParentRepo repo;
#GetMapping("/parent")
public void get() {
Child c1 = Child.builder().childId(1).name("s1").build();
Child c2 = Child.builder().childId(2).name("s2").build();
List<Child> children = new ArrayList<>();
children.add(c1);
children.add(c2);
Parent parent = Parent.builder().parentId(1).name("PARENT")
.children(children)
.build();
Parent savedParent = repo.save(parent);
}
}
Tables -
CREATE TABLE public.parent
(
parent_id integer NOT NULL,
name character varying(255) COLLATE pg_catalog."default",
CONSTRAINT parent_pkey PRIMARY KEY (parent_id)
)WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
CREATE TABLE public.child
(
child_id integer NOT NULL,
name character varying(255) COLLATE pg_catalog."default",
parent_id integer NOT NULL,
CONSTRAINT child_pkey PRIMARY KEY (child_id),
CONSTRAINT fk7dag1cncltpyhoc2mbwka356h FOREIGN KEY (parent_id)
REFERENCES public.parent (parent_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
I'm getting error while persisting child record.
Error -
Hibernate:
insert
into
child
(name, child_id)
values
(?, ?)
2022-07-19 23:12:31.727 WARN 20940 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23502
2022-07-19 23:12:31.727 ERROR 20940 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: null value in column "parent_id" violates not-null constraint
Detail: Failing row contains (1, s1, null).
2022-07-19 23:12:31.728 INFO 20940 --- [nio-8080-exec-2] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
2022-07-19 23:12:31.754 ERROR 20940 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [parent_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: null value in column "parent_id" violates not-null constraint
Detail: Failing row contains (1, s1, null).
Not sure how hibernate will pick and assign the foreign key to child.
You have to set the bidirectional relationship first
public class Parent {
#Id
private Integer parentId;
private String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> children;
public void addChild(Child child) {
this.children.add(child);
child.setParent(this);
}
}
and add the children via that method.

InvalidDataAccessResourceUsageException: org.hibernate.exception.SQLGrammarException:

I have the following problem I have been stuck for a while:
I get this error:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [call next value for hibernate_sequence]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
I found out that people with this error get it because they use reserve words for table names but I do not think this is my issue.
My two model classes are as follows. I am skipping the getters/setters and consturctors
#Entity
#Table(name = "GATEWAY_MODEL")
public class GetewayModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "serial_number", nullable = false, length = 12, updatable = true)
private String serialNumber;
#Column(name = "name", nullable = false, length = 12, updatable = true)
private String name;
#Column(name = "ipFour", nullable = false, length = 12, updatable = true)
private String ipFour;
#Column(name = "peripheral_devices", updatable = true)
#OneToMany(cascade = CascadeType.ALL, mappedBy = "gateway")
private Set<PeripheralDevicesModel> peripheralDevices = new HashSet<PeripheralDevicesModel>();
#Entity
#Table(name = "PERIPHERAL_DIVICES_MODEL")
public class PeripheralDevicesModel {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "uID", nullable = false)
private String uID;
#Column(name = "vendor", nullable = false)
private String vendor;
#Column(name = "date_created", nullable = false)
private Date dateCreated;
#Enumerated(EnumType.STRING)
#Column(name = "status")
private Status status;
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "gateway")
private GetewayModel gateway;
Then in the main class I try to put some data like this:
#Bean
CommandLineRunner initDatabase(GatewayRepository gatewayRepo, PeripheralDevicesRepository devicesRepo) {
Set<PeripheralDevicesModel> devicesSet = new HashSet<>();
GetewayModel gateway = new GetewayModel();
gateway.setId(123l);
gateway.setSerialNumber("1123");
gateway.setName("gateway");
gateway.setIpFour("1.160.10.240");
PeripheralDevicesModel devices = new PeripheralDevicesModel();
devices.setId(1234l);
devices.setuID("2");
devices.setDateCreated(new Date());
devices.setGateway(gateway);
devices.setStatus(Status.OFFLINE);
devices.setVendor("vendor");
devicesSet.add(devices);
gateway.setPeripheralDevices(devicesSet);
return args -> {
gatewayRepo.save(gateway);
devicesRepo.save(devices);
};
I am guessing that are is some issue because of the OneToMany Relationship in my model data.
I bit more from the stack trace
call next value for hibernate_sequence
2020-06-26 08:34:53 - SQL Error: 90036, SQLState: 90036
2020-06-26 08:34:53 - Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]
2020-06-26 08:34:53 -
Do you have any idea how to resolve this or why it is not working.
Thanks
configuration.properties:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Enabling H2 Console
spring.h2.console.enabled=true
# Custom H2 Console URL
spring.h2.console.path=/h2
spring.jpa.hibernate.ddl-auto=none
#Turn Statistics on and log SQL stmts
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=false
#logging.level.org.hibernate.type=trace
#logging.level.org.hibernate.stat=debug
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
Update:
After making GenerationType.IDENTITY I got the following error now:
Hibernate:
select
getewaymod0_.id as id1_0_1_,
getewaymod0_.ip_four as ip_four2_0_1_,
getewaymod0_.name as name3_0_1_,
getewaymod0_.serial_number as serial_n4_0_1_,
peripheral1_.gateway as gateway5_1_3_,
peripheral1_.id as id1_1_3_,
peripheral1_.id as id1_1_0_,
peripheral1_.date_created as date_cre2_1_0_,
peripheral1_.gateway as gateway5_1_0_,
peripheral1_.uid as uid3_1_0_,
peripheral1_.vendor as vendor4_1_0_
from
gateway_model getewaymod0_
left outer join
peripheral_divices_model peripheral1_
on getewaymod0_.id=peripheral1_.gateway
where
getewaymod0_.id=?
2020-06-26 16:42:04 - SQL Error: 42102, SQLState: 42S02
2020-06-26 16:42:04 - Table "GATEWAY_MODEL" not found; SQL statement:
select getewaymod0_.id as id1_0_1_, getewaymod0_.ip_four as ip_four2_0_1_, getewaymod0_.name as name3_0_1_, getewaymod0_.serial_number as serial_n4_0_1_, peripheral1_.gateway as gateway5_1_3_, peripheral1_.id as id1_1_3_, peripheral1_.id as id1_1_0_, peripheral1_.date_created as date_cre2_1_0_, peripheral1_.gateway as gateway5_1_0_, peripheral1_.uid as uid3_1_0_, peripheral1_.vendor as vendor4_1_0_ from gateway_model getewaymod0_ left outer join peripheral_divices_model peripheral1_ on getewaymod0_.id=peripheral1_.gateway where getewaymod0_.id=? [42102-200]
2020-06-26 16:42:04 - HHH000327: Error performing load command
org.hibernate.exception.SQLGrammarException: could not prepare statement
I changed 2 things(besides the few grammar/typo errors in your code):
Added cascade=CascadeType.ALL as follows:
#JsonIgnore
#ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "gateway")
private GatewayModel gateway;
You can't add an entity, which has columns with nullable = false:
devices.setGateway(new GetewayModel());
devices.setGateway(gateway);
Otherwise, it's working fine on H2.
UPDATE:
Grammar/typo errors to look for:
#Table(name = "PERIPHERAL_DIVICES_MODEL") needs to be #Table(name = "PERIPHERAL_DEVICES_MODEL")
public class GetewayModel needs to be public class GatewayModel
private GetewayModel gateway; needs to be private GatewayModel gateway;
Ran into the same problem. The difference was that I did not specify strategy in #GeneratedValues. Turns out the default strategy is GeneratedType.AUTO.
So Simon Martinelli's comment solves my issue, by explicitly specify #GeneratedValue(strategy = GenerationType.IDENTITY) for the id column/field.
This article summarises the strategies nicely.
GenerationType.Identity does not create any additional sequence tables like GenerationType.AUTO / GenerationType.SEQUENCE and also maintain the sequences in every table starts from 0, rather than maintaining the sequence number across the tables like GenerationType.AUTO does it.
GenerationType.AUTO generates one more table named hibernate_sequences for maintaining the sequences.
GenerationType.SEQUENCE is purely customizable, probably every auto generation field would have configured with separate sequences.

How to fix syntax error parsing JPQL with group by

I'm new using JPA and JPQL for a project, but I got SQL syntax error and I couldn't find the cause.
I'm using spring boot, MySQL.
I got a vote repository
public interface VoteRepository extends JpaRepository<Vote, Long> {
....
#Query(value = "SELECT NEW com.self.polls.model.ChoiceVoteCount(v.choice.id, count(v.id)) FROM Vote v WHERE v.poll.id = :pollId GROUP BY v.choice.id", nativeQuery = true)
List<ChoiceVoteCount> countByPollIdGroupByChoiceId(#Param("pollId") Long pollId);
....
}
ChoiceVoteCount
public class ChoiceVoteCount {
private Long choiceId;
private Long voteCount;
}
Vote
public class Vote {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "poll_id", nullable = false)
private Poll poll;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "choice_id", nullable = false)
private Choice choice;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "user_id", nullable = false)
private User user;
}
But I got error when running this query
2019-03-27 16:01:34.783 ERROR 68064 --- [nio-5000-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.self.polls.model.ChoiceVoteCount(v.choice.id, count(v.id)) FROM Vote v WHERE v.' at line 1
2019-03-27 16:01:34.787 ERROR 68064 --- [nio-5000-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.self.polls.model.ChoiceVoteCount(v.choice.id, count(v.id)) FROM Vote v WHERE v.' at line 1
You have to add a constructor in ChoiceVoteCount.
To play safe, the default constructor could also be added.
public ChoiceVoteCount() {
}
public ChoiceVoteCount(Long choiceId, Long voteCount) {
this.choiceId = choiceId;
this.voteCount = voteCount;
}

JPA update record is failing due to #OneToMany

I have a very small doubt regarding #OneToMany mapping.
I have a model student and another model attendance.
A student can have multiple attendance. but student model should only be able to retrieve the attendance info.
But when I am trying to change some student info I am getting below error as it is trying to update attendance record.
here is my mapping
#Entity
#Table(name="student_detail")
#Getter #Setter
public class StudentDetailsModel {
#Id
#Column(name="reg_no",updatable = false, nullable = false)
private String regNo;
#OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
#JoinColumn(name = "reg_no")
private List<AttendanceModel> attendances;
}
and the exception I a getting.
update
student_detail
set
address=?,
alt_contact_number=?,
blood_group=?,
contact_number=?,
dob=?,
father_name=?,
first_name=?,
gender=?,
last_name=?,
middle_name=?,
mother_name=?,
photo_url=?,
school_id=?
where
reg_no=?
Hibernate:
update
attendance
set
reg_no=null
where
reg_no=?
2019-01-13 12:12:52.922 WARN 10708 --- [nio-8081-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 23502
2019-01-13 12:12:52.923 ERROR 10708 --- [nio-8081-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: null value in column "reg_no" violates not-null constraint
Detail: Failing row contains (null, 1, 2019-01-05, t, 2).
2019-01-13 12:12:52.926 INFO 10708 --- [nio-8081-exec-1] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [reg_no]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
my attenance model is as follows
#Entity
#Table(name="attendance")
#Getter #Setter
public class AttendanceModel {
//#EmbeddedId
//private AttendanceId attendanceId;
#Id
#Column(name="attendance_id")
private long id;
#Column(name="reg_no")
private String regNo;
#Column(name="subject_id")
private long subjectId;
#Column(name="class_date")
private Date classDate;
#Column(name="present")
private boolean present;
}
Could you show me Student Model.If i look your code post : You using Unidirectional relationship.
I think it must :
#OneToMany(fetch = FetchType.LAZY , cascade = CascedeType.ALL)
#JoinColumn(name="attendance_id")
private List<AttendanceModel> attendances = new ArrayList<>();

Column does not exist in spring boot Postgres app

Hi in my spring boot postgresql application, when i retrieve all record using DAO it show column does not exists.
ERROR
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42703
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: column merchantit0_.id does not exist
Position: 8
ERROR: org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/customerplus].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [/customerplus] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: ERROR: column merchantit0_.id does not exist
Position: 8
Entity Domain
#Entity
#Table(name = "merchant_item_category")
public class MerchantItemCategory{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false, length = 11)
private long id;
#ManyToOne
#JoinColumn(name = "merchant_id", nullable = false)
private Merchant merchant;
// getters and setters
}
DAO
public List<MerchantItemCategory> getAllMerchantItemCategoryByMerchantId(long id) {
Session session=getSession();
List<MerchantItemCategory>itemCategories=session.createQuery("from MerchantItemCategory where merchant.id=:merchantId and isDelete='0' order by categoryName asc")
.setParameter("merchantId", id)
.list();
return itemCategories;
}
I just checked every object and it is correct, But how this error occurring..!
A potential cause of this error is when you haven't defined the hibernate "default schema" property.
I fixed this issue by adding line below to my application.properties:
spring.jpa.properties.hibernate.default_schema=${your-default-schema-name}

Categories

Resources