I'v got a problem in my Spring Boot with H2 project. I got a get method for listing elements from the SQL table and the SQL command working. In the H2 database I can execute and see the results but I can't get the values from Postman. My GET post went wrong. My SQL codes are also in here.
I also uploaded my project to github. If you want to see all classes Here is my GitHub project link
UrunEntity class
#Entity
#Table(name = "urunler")
public class UrunEntity{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "urun_id")
private int urunId;
#Column(name = "hayvan_kupe_no")
private int hayvanKupeNo;
#Column(name = "hayvan_adi")
private String hayvanAdi;
#Column(name = "dogum_sekli")
private String dogumSekli;
#Column(name = "hayvan_resmi")
private String hayvanResmi;
#Column(name = "hayvan_cinsiyet")
private String hayvanCinsiyet;
#Column(name = "hayvan_irki")
private String hayvanIrki;
#Column(name = "hayvan_anneAdi")
private String hayvanAnneAdi;
#Column(name = "dogum_tarihi")
private String dogumTarihi;
#Column(name = "dogum_agirligi")
private Double dogumAgirligi;
#Column(name = "tohuma_hazir")
private Boolean tohumaHazir;
#Column(name = "sut_miktari")
private Double sutMiktari;
#Column(name = "sut_tarihi")
private String sutTarihi;
#Column(name = "urun_tutar")
private Double urunTutar;
#Column(name = "user_id")
private Integer userId;
//getters and setters after that
Here is my UrunRepository
#Query(value="SELECT DOGUM_AGIRLIGI, DOGUM_SEKLI, DOGUM_TARIHI, HAYVAN_ADI, HAYVAN_ANNE_ADI, HAYVAN_CINSIYET, HAYVAN_IRKI, URUN_TUTAR FROM URUNLER d " +
"INNER JOIN kullanicilar k on d.user_id = k.user_id " +
"WHERE k.user_id=:userId AND HAYVAN_ADI IS NOT NULL",
nativeQuery=true)
List<UrunEntity> findHayvanAll(#Param("userId") String userId);
Here is the error code at backend
> 2021-01-12 17:58:39.357 WARN 19652 --- [nio-6161-exec-5] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 42122, SQLState: 42S22
2021-01-12 17:58:39.357 ERROR 19652 --- [nio-6161-exec-5] o.h.engine.jdbc.spi.SqlExceptionHelper : Column "urun_id" not found [42122-200]
2021-01-12 17:58:39.374 ERROR 19652 --- [nio-6161-exec-5] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/invoiceControl] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [SELECT DOGUM_AGIRLIGI, DOGUM_SEKLI, DOGUM_TARIHI, HAYVAN_ADI, HAYVAN_ANNE_ADI, HAYVAN_CINSIYET, HAYVAN_IRKI, URUN_TUTAR FROM URUNLER d INNER JOIN kullanicilar k on d.user_id = k.user_id WHERE k.user_id=? AND HAYVAN_ADI IS NOT NULL]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query] with root cause
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "urun_id" not found [42122-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:453) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:205) ~[h2-1.4.200.jar:1.4.200]
at org.h2.message.DbException.get(DbException.java:181) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcResultSet.getColumnIndex(JdbcResultSet.java:3169) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcResultSet.get(JdbcResultSet.java:3268) ~[h2-1.4.200.jar:1.4.200]
at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:352) ~[h2-1.4.200.jar:1.4.200]
Here is the error from Postman:
"timestamp": "2021-01-12T14:30:50.458+0000",
"status": 500,
"error": "Internal Server Error",
"message": "could not execute query; SQL [SELECT SUT_MIKTARI, SUT_TARIHI, URUN_TUTAR FROM URUNLER d INNER JOIN kullanicilar k on d.user_id = k.user_id WHERE k.user_id=? AND SUT_MIKTARI IS NOT NULL]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query",
"trace": "org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [SELECT SUT_MIKTARI, SUT_TARIHI, URUN_TUTAR FROM URUNLER d INNER JOIN kullanicilar k on d.user_id = k.user_id WHERE k.user_id=? AND SUT_MIKTARI IS NOT NULL]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query\r\n\tat org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:281)\r\n\tat org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)\r\n\tat org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)\r\n\tat org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)\r\n\tat org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)\r\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)\r\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\r\n\tat org.springframework.data.jpa.repository.support
KullanicilarEntity class
#Entity
#Table(name = "kullanicilar")
public class KullaniciEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private long userId;
#Column(name = "email")
private String email;
#Column(name = "kullanici_sifre")
private String kullaniciSifre;
#Column(name = "kullanici_adi")
private String kullaniciAdi;
#Column(name = "kullanici_soyadi")
private String kullaniciSoyadi;
#Column(name = "telefon_no")
private String telefonNo;
#Column(name = "enabled")
private boolean enabled;
#Column(name = "username")
private String username;
My Resource(endpoints) interface
#GetMapping(path = "/getSut")
public ResponseEntity<List<UrunEntity>> getSut(#RequestParam("userId") String userId) {
List<UrunEntity> urunEntities = ccAppService.findSutAll(userId);
return new ResponseEntity(urunEntities, HttpStatus.OK);
}
Seems like you want to materialize an entity from a native query, but the native query is not selecting the urun_id column which is required to materialize the entity. Try using HQL queries instead of native queries.
You are trying to map fields not fully fitting your entity. Try also selecting urun_id in your query or d.* in the selection part.
For more complex queries you can use SqlResultSetMapping. Check this link.
I create a new model class named HayvanDto and I created all of the UrunEntity entites inside of this.
public class HayvanDto {
private Double dogumAgirligi;
private String dogumSekli;
private String dogumTarihi;
private String hayvanAdi;
private String hayvanAnneAdi;
private String hayvanCinsiyet;
private String hayvanIrki;
private String hayvanResmi;
private Boolean tohumaHazir;
private Double urunTutar;
After that, in my implementation class, I wrote this code.
#Override
public List<HayvanDto> findHayvanAll(Integer userId) {
List<UrunEntity> urunEntities = urunRepository.findHayvanAll(userId);
List<HayvanDto> hayvanDtos = new ArrayList<>();
for (UrunEntity urunEntity : urunEntities) {
HayvanDto hayvanDto = new HayvanDto();
hayvanDto.setHayvanAdi(urunEntity.getHayvanAdi());
hayvanDto.setHayvanIrki(urunEntity.getHayvanIrki());
hayvanDto.setHayvanResmi(urunEntity.getHayvanResmi());
hayvanDto.setHayvanCinsiyet(urunEntity.getHayvanCinsiyet());
hayvanDto.setHayvanAnneAdi(urunEntity.getHayvanAnneAdi());
hayvanDto.setDogumAgirligi(urunEntity.getDogumAgirligi());
hayvanDto.setDogumSekli(urunEntity.getDogumSekli());
hayvanDto.setUrunTutar(urunEntity.getUrunTutar());
hayvanDto.setTohumaHazir(urunEntity.getTohumaHazir());
hayvanDtos.add(hayvanDto);
}
return hayvanDtos;
}
Then it worked. Thanks for the answers.
Related
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.
I'm trying to create a Named query with the inner join condition in the Entity class.
However the application is failing to start with an exception.
Entity:
#Entity
#Table(name = "fooentry")
#NamedQuery(name="query1", query="SELECT foo.id, foo.name, foo.type, foo.action, foo.createdDateTime FROM FooEntity foo " +
"INNER JOIN (SELECT name, type, MAX(createdDateTime) AS recenttime FROM FooEntity GROUP BY name, type) recententry " +
"ON (foo.name = recententry.name AND foo.type = recententry.type) AND createdDateTime = recenttime AND isExported = false",
lockMode=PESSIMISTIC_WRITE)
public class FooEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
#NotNull
private String msisdn;
#Column(name = "type")
#NotNull
private String iccid;
#Column(name = "action")
#NotNull
private Long inventoryActionId;
#NotNull
#Column(name = "is_exported")
private Boolean isExported;
#Column(name = "created_date_time")
#NotNull
private LocalDateTime createdDateTime;
//setter and getter
}
Exception:
Application is failing to start with the following exception.
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.HibernateException: Errors in named queries:
query1 failed because of: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ( near line 1, column 161
You can try query like below. It should return expected result
SELECT foo.id, foo.name, foo.type, foo.action, foo.createdDateTime
FROM FooEntity foo
WHERE
foo.isExported = false AND
EXISTS(
SELECT recententry.name, recententry.type, MAX(recententry.createdDateTime) AS recenttime
FROM FooEntity recententry
WHERE recententry.name = foo.name AND recententry.type = foo.type
GROUP BY recententry.name, recententry.type
HAVING recententry.recenttime = foo.createdDateTime
)
I'm getting error "column "systementi0_.Id does not exist". I'm using PostgreSql and Hibernate.
There is code of my entity:
#Entity
#Table(name = "system_table", schema = "blue_schema")
public class SystemEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "Id", unique = true)
private int id;
#Column(name = "name")
private String name;
#Column(name = "sys_description")
private String systemDescription;
#Column(name = "tech_description")
private String technologyDescritpion;
#Column(name = "owner_name")
private String owner;
public SystemEntity() {
// TODO Auto-generated constructor stub
}
public SystemEntity(int id, String name, String systemDescription, String technologyDescritpion, String owner) {
super();
this.id = id;
this.name = name;
this.systemDescription = systemDescription;
this.technologyDescritpion = technologyDescritpion;
this.owner = owner;
}
public SystemEntity(String name, String systemDescription, String technologyDescritpion, String owner) {
super();
this.name = name;
this.systemDescription = systemDescription;
this.technologyDescritpion = technologyDescritpion;
this.owner = owner;
}
At the beggining I'm trying to get every data from this table from DB.
#Override
public List<SystemEntity> getAllSystems() {
Session currentSession = sessionFactory.getCurrentSession();
Query<SystemEntity> theQuery = currentSession.createQuery("from SystemEntity", SystemEntity.class);
List<SystemEntity> listOfSystems = theQuery.getResultList();
return listOfSystems;
}
That's my database types and output:
Table output
Table types
My schema name is clarified in #Table annotation, but still getting error:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/ContractManager] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
org.postgresql.util.PSQLException: Error: columnsystementi0_.id does not exist.
I saw similar post like mine but solution was simple, just add schema name in #Table.
It's a common mistake. The first recommendation: don't use uppercase in the name of all database entities: schemas, tables or columns.
Your id column name has "Id". Try "id".
The second: I recommend you in postresql use sequence generator:
#Entity
#Table(name = "system_table", schema = "blue_schema")
#SequenceGenerator(schema = "blue_schema", name = "system_table_seq", allocationSize = 1, sequenceName = "system_table_seq")
public class SystemEntity {
// other code below
// ...
}
And the last recommendation: don't use primitive types in JPA entities.
Try to:
#Entity
#Table(name = "system_table", schema = "blue_schema")
#SequenceGenerator(schema = "blue_schema", name = "system_table_seq", allocationSize = 1, sequenceName = "system_table_seq")
public class SystemEntity {
#Id
#GeneratedValue(generator = "system_table_seq", strategy = GenerationType.SEQUENCE)
private Integer id;
// other code below
// ...
}
trying to run a native query however I'm getting The column name sb_modelid is not valid. when attempting to map the return object to my model object in java? I have verified all the column names are correct.
1) Why is it referring to my column name as sb_modelid and not sbModelID?
2) Why is not being mapped to my POJO correctly?
Thanks!
Model Object:
package com.dish.wfm.linkingTickets.model.repository;
public class Model {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "sbModelID")
private Long sbModelId;
#Column(name = "modelID")
private String modelID;
#Column(name = "serialNumber")
private String serialNumber;
#Column(name = "serviceContractNumber")
private String serviceContractNumber;
}
Repo:
#Repository
public interface SBModelRepo extends JpaRepository<Model, Long> {
#Query(value = "select m.sbModelID, m.modelID, m.serialNumber, m.serviceContractNumber from sb.Model m where m.modelID = ?1 and m.serialNumber = ?2", nativeQuery = true)
Model findTopByModelIDAndSerialNumber(String modelID, String serialNumber);
}
I tried that:
#Query("SELECT AVG(a.unitPrice) FROM ConnectwiseAgreementAdditions a WHERE a.agreementId = :agreementId " +
"AND a.productId IN (SELECT p.id FROM ConnectwiseProductFindResult p " +
"WHERE LOWER(p.subCategory) LIKE LOWER('%server%') " +
"OR LOWER(p.subCategory) LIKE LOWER('%workstation%'))")
BigDecimal geAgreementDevicetUnitPrice(#Param("agreementId") Integer agreementId);
But i have exception:
2016-05-11 14:58:05.773 ERROR 28016 --- [main] o.h.e.j.s.SqlExceptionHelper : ERROR: type "double" does not exist
Position: 44
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
What is wrong?
I use Postgresql driver.
UPDATE
My entity:
#Entity
#Table(name = "connectwise_agreement_additions")
public class ConnectwiseAgreementAdditions {
#Id
#Column
private Integer id;
#Column(columnDefinition = "DEFAULT false")
private boolean normalize = false;
#Column(name = "agreement_id", columnDefinition = "NUMERIC(18,2)")
private Integer agreementId;
#Column(name = "product_id")
private Integer productId;
#Column(name = "unit_price", columnDefinition = "NUMERIC(18,2)")
private BigDecimal unitPrice;
}