jpa project with wampserver cant put anything to DB - mysql

I've created a database and added the employee table with the following code
CREATE TABLE IF NOT EXISTS `employee` (
`Idemployee` int(11) NOT NULL,
`fIrstname` varchar(45) DEFAULT NULL,
`lastname` varchar(45) DEFAULT NULL,
`emaIl` varchar(45) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
--
--
--
INSERT INTO `employee` (`Idemployee`, `fIrstname`, `lastname`, `emaIl`) VALUES
(2, 'Pranil', 'kharkar', 'someMail#gmail.com'),
(5, 'prasad', 'kharkar', 'someMail#gmail.com'),
(8, 'prasad', 'kharkar', 'someMail#gmail.com'),
(9, 'prasad', 'kharkar', 'someMail#gmail.com'),
(10, 'Pranil', 'kharkar', 'someMail#gmail.com'),
(11, 'Pranil', 'kharkar', 'someMail#gmail.com'),
(13, 'prasad', 'kharkar', 'someMail#gmail.com'),
(14, 'prasad', 'kharkar', 'someMail#gmail.com'),
(15, 'Murat', 'Kandemir', 'cmkTurkiye#gmail.com'),
(16, 'Murat2', 'Kandemir2', 'cmkTurkiye#gmail.com');
--
--
--
--
ALTER TABLE `employee`
ADD PRIMARY KEY (`Idemployee`);
--
--
--
--
--
--
ALTER TABLE `employee`
MODIFY `Idemployee` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=17;
and then created jpa project and created these 2 code pieces below for adding someone to table;
package com.thejavageek.jpa;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.thejavageek.jpa.entities.Employee;
public class Test {
public static void main(String[] args) throws IOException {
/* Create EntityManagerFactory */
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("kurumsaljava");
/* Create and populate Entity */
Employee employee = new Employee();
employee.setFirstname("Ahmet");
employee.setLastname("Mercan");
employee.setEmail("cmkTurkiye#gmail.com");
//employee.setIdEmployee();
/* Create EntityManager */
EntityManager em = emf.createEntityManager();
/* Persist entity */
em.getTransaction().begin();
em.persist(employee);
em.getTransaction().commit();
/* CMK UPDATE
*/
/* Update routines begin*/
/*
int iEdit = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter Employee Number To Edit");
//String iEdit = br.readLine();
try{
iEdit = Integer.parseInt(br.readLine());
}catch(NumberFormatException nfe){
System.err.println("Invalid Format!");
}
employee = em.find(Employee.class, iEdit);
em.getTransaction().begin();
employee.setFirstname("Murat7");
employee.setLastname("Celal");
System.out.println("Employee after updation :- " + employee);
em.getTransaction().commit();
*/
/*Update routines finish*/
// CMK DELETE
/* Delete routines begin*/
/*
int iRemove = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter Employee Number To Remove");
try{
iRemove = Integer.parseInt(br.readLine());
}catch(NumberFormatException nfe){
System.err.println("Invalid Format!");
}
// Remove entity
employee = em.find(Employee.class, iRemove);
System.out.println(employee);
em.getTransaction().begin();
em.remove(employee);
em.getTransaction().commit();
*/
/*Delete routines finish*/
/* CMK
*/
/* Retrieve entity */
/*
employee = em.find(Employee.class, iEdit);
System.out.println(employee);
*/
/* Check whether entity is removed or not */
/*employee = em.find(Employee.class, 1);
System.out.println("Employee after removal :- " + employee);*/
}
}
and Employee.java;
package com.thejavageek.jpa.entities;
import java.io.Serializable;
import javax.persistence.*;
/**
* Entity implementation class for Entity: Employee
*
*/
#Entity
public class Employee implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6984979000774926570L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int idEmployee;
private String email;
private String firstname;
private String lastname;
public Employee() {
}
public int getIdEmployee() {
return this.idEmployee;
}
public void setIdEmployee(int IdEmployee) {
this.idEmployee = IdEmployee;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
#Override
public String toString() {
return "Employee [email=" + email
+ ", firstname=" + firstname + ", lastname=" + lastname + "]";
}
}
and persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="kurumsaljava">
<class>com.thejavageek.jpa.entities.Employee</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/kurumsaljava?useSSL=false" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
</properties>
</persistence-unit>
</persistence>
database name is kurumsaljava.I am getting these errors couldnt solve them
[EL Warning]: 2016-04-27 15:45:04.913--UnitOfWork(1576499395)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '?L, F?RSTNAME, LASTNAME) VALUES ('cmkTurkiye#gmail.com', 'Ahmet', 'Mercan')' at line 1
Error Code: 1064
Call: INSERT INTO EMPLOYEE (EMAİL, FİRSTNAME, LASTNAME) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(Employee [email=cmkTurkiye#gmail.com, firstname=Ahmet, lastname=Mercan])
Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '?L, F?RSTNAME, LASTNAME) VALUES ('cmkTurkiye#gmail.com', 'Ahmet', 'Mercan')' at line 1
Error Code: 1064
Call: INSERT INTO EMPLOYEE (EMAİL, FİRSTNAME, LASTNAME) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(Employee [email=cmkTurkiye#gmail.com, firstname=Ahmet, lastname=Mercan])
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
at com.thejavageek.jpa.Test.main(Test.java:35)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '?L, F?RSTNAME, LASTNAME) VALUES ('cmkTurkiye#gmail.com', 'Ahmet', 'Mercan')' at line 1
Error Code: 1064
Call: INSERT INTO EMPLOYEE (EMAİL, FİRSTNAME, LASTNAME) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(Employee [email=cmkTurkiye#gmail.com, firstname=Ahmet, lastname=Mercan])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:900)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4207)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
... 1 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '?L, F?RSTNAME, LASTNAME) VALUES ('cmkTurkiye#gmail.com', 'Ahmet', 'Mercan')' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:939)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
... 32 more
waiting for your answers.

As RiggsFolly said above i changed the Employee class's this parts i's to I;
#Override
public String toString() {
return "Employee [email=" + email
+ ", firstname=" + firstname + ", lastname=" + lastname + "]";
}
}
and added some addition to persistence.xml's connection string;
localhost:3306/example?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
and it is working thx

Related

Pomelo.EntityFrameworkCore.MySql problem when access property

Today I migrate my project to .NET 6 with MySql db.
I tried Pomelo.EntityFrameworkCore.MySql for the first time but several errors had occur.
I fixed some of them but the last one, I couldn`t.
System.InvalidOperationException: The property 'SqlClass.Disabled' is of type 'byte' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
entity.Property(e => e.Disabled)
//.HasConversion<int>()
.IsRequired()
.HasMaxLength(255)
.HasColumnName("disabled")
.HasColumnType("tinyint(1)");
[Required]
[MaxLength(255)]
public byte Disabled { get; set; }
Any ideas ? Thank you.
There are basically 3 simple options, all demonstrated here with the IceCream.Available property:
1. Use System.Boolean instead of System.Byte
Pomelo translates tinyint(1) to System.Boolean by default. So if you change the CLR type of your property from byte to bool, it works out-of-the box:
Program.cs
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace IssueConsoleTemplate
{
public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
[Required]
[Column(TypeName = "tinyint(1)")] // <-- redundant (bool is translated to tinyint(1) by default)
public bool Available { get; set; } // <-- use bool
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So70198786";
var serverVersion = ServerVersion.AutoDetect(connectionString);
optionsBuilder
.UseMySql(connectionString, serverVersion)
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IceCream>(
entity =>
{
// Not needed if you are using data annotations:
//
// entity.Property(e => e.Available)
// .IsRequired()
// .HasColumnType("tinyint(1)"); // <-- redundant (bool is translated to tinyint(1) by default)
entity.HasData(
new IceCream
{
IceCreamId = 1,
Name = "Vanilla",
Available = true, // <-- bool
},
new IceCream
{
IceCreamId = 2,
Name = "Chocolate",
Available = false, // <-- bool
});
});
}
}
internal static class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var availableIceCreams = context.IceCreams
.Where(i => i.Available) // <-- bool
.ToList();
Trace.Assert(availableIceCreams.Count == 1);
Trace.Assert(availableIceCreams[0].Name == "Vanilla");
}
}
}
Output (SQL)
warn: Microsoft.EntityFrameworkCore.Model.Validation[10400]
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.0 initialized 'Context' using provider 'Pomelo.EntityFrameworkCore.MySql:6.0.0-rtm.1' with options: ServerVersion 8.0.25-mysql SensitiveDataLoggingEnabled DetailedErrorsEnabled
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (38ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DROP DATABASE `So70198786`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE `So70198786`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER DATABASE CHARACTER SET utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (47ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `IceCreams` (
`IceCreamId` int NOT NULL AUTO_INCREMENT,
`Name` longtext CHARACTER SET utf8mb4 NULL,
`Available` tinyint(1) NOT NULL,
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
) CHARACTER SET=utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (1, TRUE, 'Vanilla');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (2, FALSE, 'Chocolate');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `i`.`IceCreamId`, `i`.`Available`, `i`.`Name`
FROM `IceCreams` AS `i`
WHERE `i`.`Available`
2. Use tinyint instead of tinyint(1)
In case you definitely want to use System.Byte as the CLR type of your property, use tinyint instead of tinyint(1). All tinyint except tinyint(1) are translated to System.Byte by default:
Program.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace IssueConsoleTemplate
{
public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
[Required]
[Column(TypeName = "tinyint")] // <-- redundant (byte is translated to tinyint by default)
public byte Available { get; set; }
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So70198786_01";
var serverVersion = ServerVersion.AutoDetect(connectionString);
optionsBuilder
.UseMySql(connectionString, serverVersion)
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IceCream>(
entity =>
{
// Not needed if you are using data annotations:
//
// entity.Property(e => e.Available)
// .IsRequired()
// .HasColumnType("tinyint"); // <-- redundant (byte is translated to tinyint by default)
entity.HasData(
new IceCream
{
IceCreamId = 1,
Name = "Vanilla",
Available = 1, // <-- byte
},
new IceCream
{
IceCreamId = 2,
Name = "Chocolate",
Available = 0, // <-- byte
});
});
}
}
internal static class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var availableIceCreams = context.IceCreams
.Where(i => i.Available != 0) // <-- byte
.ToList();
Trace.Assert(availableIceCreams.Count == 1);
Trace.Assert(availableIceCreams[0].Name == "Vanilla");
}
}
}
Output (SQL)
warn: Microsoft.EntityFrameworkCore.Model.Validation[10400]
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.0 initialized 'Context' using provider 'Pomelo.EntityFrameworkCore.MySql:6.0.0-rtm.1' with options: ServerVersion 8.0.25-mysql SensitiveDataLoggingEnabled DetailedErrorsEnabled
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (42ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DROP DATABASE `So70198786_01`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (41ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE `So70198786_01`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (19ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER DATABASE CHARACTER SET utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (48ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `IceCreams` (
`IceCreamId` int NOT NULL AUTO_INCREMENT,
`Name` longtext CHARACTER SET utf8mb4 NULL,
`Available` tinyint NOT NULL,
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
) CHARACTER SET=utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (1, 1, 'Vanilla');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (10ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (2, 0, 'Chocolate');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `i`.`IceCreamId`, `i`.`Available`, `i`.`Name`
FROM `IceCreams` AS `i`
WHERE `i`.`Available` <> 0
3. Change default System.Boolean mapping to bit(1) or remove it altogether
Finally, if you need to map exactly tinyint(1) to System.Byte, then you can change the default mapping that Pomelo is using for System.Boolean by setting a DbContext option in your UseMySql() call:
Program.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
namespace IssueConsoleTemplate
{
public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
[Required]
[Column(TypeName = "tinyint(1)")] // <-- necessary (otherwise gets translated to tinyint)
public byte Available { get; set; }
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = "server=127.0.0.1;port=3306;user=root;password=;database=So70198786_02";
var serverVersion = ServerVersion.AutoDetect(connectionString);
optionsBuilder
.UseMySql(
connectionString,
serverVersion,
options => options.DefaultDataTypeMappings( // <-- change default data type mappings
m => m.WithClrBoolean(MySqlBooleanType.Bit1))) // <-- or even MySqlBooleanType.None
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IceCream>(
entity =>
{
// Not needed if you are using data annotations:
//
// entity.Property(e => e.Available)
// .IsRequired()
// .HasColumnType("tinyint(1)"); // <-- necessary (otherwise gets translated to tinyint)
entity.HasData(
new IceCream
{
IceCreamId = 1,
Name = "Vanilla",
Available = 1, // <-- byte
},
new IceCream
{
IceCreamId = 2,
Name = "Chocolate",
Available = 0, // <-- byte
});
});
}
}
internal static class Program
{
private static void Main()
{
using var context = new Context();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var availableIceCreams = context.IceCreams
.Where(i => i.Available != 0) // <-- byte
.ToList();
Trace.Assert(availableIceCreams.Count == 1);
Trace.Assert(availableIceCreams[0].Name == "Vanilla");
}
}
}
Output (SQL)
warn: Microsoft.EntityFrameworkCore.Model.Validation[10400]
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.0 initialized 'Context' using provider 'Pomelo.EntityFrameworkCore.MySql:6.0.0-rtm.1' with options: ServerVersion 8.0.25-mysql SensitiveDataLoggingEnabled DetailedErrorsEnabled
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (40ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DROP DATABASE `So70198786_02`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE `So70198786_02`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (19ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER DATABASE CHARACTER SET utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (86ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `IceCreams` (
`IceCreamId` int NOT NULL AUTO_INCREMENT,
`Name` longtext CHARACTER SET utf8mb4 NULL,
`Available` tinyint(1) NOT NULL,
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
) CHARACTER SET=utf8mb4;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (1, 1, 'Vanilla');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`IceCreamId`, `Available`, `Name`)
VALUES (2, 0, 'Chocolate');
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `i`.`IceCreamId`, `i`.`Available`, `i`.`Name`
FROM `IceCreams` AS `i`
WHERE `i`.`Available` <> 0
Unrelated to the topic of this question, [MaxLength(255)] or .HasMaxLength(255) have no effect on non-string columns.

How to use JsonObject of Pomelo.EntityFramework

I want to store list of string into mysql table as json. I saw there is support for this in pomelo entityframework. I followed this https://libraries.io/github/tuanbs/Pomelo.EntityFrameworkCore.MySql
Here is my entity
public class Project
{
public int Id {get;set;}
public string Title {get;set;}
public JsonObject<List<string>> Tags {get;set;}
}
But when _context.Database.EnsureDeleted(); is called it gives below error
Navigation property 'Tags' on entity type 'Project' is not virtual.
UseLazyLoadingProxies requires all entity types to be public,
unsealed, have virtual navigation properties, and have a public or
protected constructor.
But it is not navigation property that I have to add virtual keyword with it but is a column. Don't know what am I missing here.
Take a look at the following sample code, that is taken from my post on our GitHub repository, and works without issues:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql.Storage;
namespace IssueConsoleTemplate
{
public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
public JsonObject<Energy> Energy { get; set; }
public JsonObject<List<string>> Comments { get; set; }
}
public class Energy
{
public double Kilojoules { get; set; }
public double Kilocalories { get; set; }
}
public class Context : DbContext
{
public virtual DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySql("server=127.0.0.1;port=3306;user=root;password=;database=So62301095",
b => b.ServerVersion(new ServerVersion("8.0.20-mysql")))
.UseLoggerFactory(LoggerFactory.Create(b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
}
internal class Program
{
private static void Main()
{
using (var context = new Context())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.IceCreams.AddRange(
new IceCream
{
Name = "Vanilla",
Energy = new Energy
{
Kilojoules = 866.0,
Kilocalories = 207.0
},
Comments = new List<string>
{
"First!",
"Delicious!"
}
},
new IceCream
{
Name = "Chocolate",
Energy = new Energy
{
Kilojoules = 904.0,
Kilocalories = 216.0
},
Comments = new List<string>
{
"My husband likes this one a lot."
}
});
context.SaveChanges();
}
using (var context = new Context())
{
var result = context.IceCreams
.OrderBy(e => e.IceCreamId)
.ToList();
Debug.Assert(result.Count == 2);
Debug.Assert(result[0].Name == "Vanilla");
Debug.Assert(result[0].Energy.Object.Kilojoules == 866.0);
Debug.Assert(result[0].Comments.Object.Count == 2);
Debug.Assert(result[0].Comments.Object[0] == "First!");
}
}
}
}
It generates the following SQL:
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.1.3 initialized 'Context' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: ServerVersion 8.0.20 MySql SensitiveDataLoggingEnabled DetailedErrorsEnabled
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (81ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DROP DATABASE `So62301095`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE DATABASE `So62301095`;
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (66ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE `IceCreams` (
`IceCreamId` int NOT NULL AUTO_INCREMENT,
`Name` longtext CHARACTER SET utf8mb4 NULL,
`Energy` json NULL,
`Comments` json NULL,
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
);
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (15ms) [Parameters=[#p0='["First!","Delicious!"]', #p1='{"Kilojoules":866.0,"Kilocalories":207.0}', #p2='Vanilla' (Size = 4000)], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`Comments`, `Energy`, `Name`)
VALUES (#p0, #p1, #p2);
SELECT `IceCreamId`
FROM `IceCreams`
WHERE ROW_COUNT() = 1 AND `IceCreamId` = LAST_INSERT_ID();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[#p0='["My husband likes this one a lot."]', #p1='{"Kilojoules":904.0,"Kilocalories":216.0}', #p2='Chocolate' (Size = 4000)], CommandType='Text', CommandTimeout='30']
INSERT INTO `IceCreams` (`Comments`, `Energy`, `Name`)
VALUES (#p0, #p1, #p2);
SELECT `IceCreamId`
FROM `IceCreams`
WHERE ROW_COUNT() = 1 AND `IceCreamId` = LAST_INSERT_ID();
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT `i`.`IceCreamId`, `i`.`Comments`, `i`.`Energy`, `i`.`Name`
FROM `IceCreams` AS `i`
ORDER BY `i`.`IceCreamId`
Take a close look at the IceCream.Comments property, that does exactly what you want.
On the same GitHub issue further below, you find another post by me, with a much more sophisticated example.
Also, we are going to implement full JSON support next for Pomelo (probably within a week).

Spring Hibernate - Invalid value for getLong() - 'United Kingdom - UTC +0:00'

I guess hibernate is trying to assign a String value fetched from the database to long.Have done many-to-one unidirectional mapping.I'm trying to display the values from the region table in a drop down in CorporateGroupForm.jsp
CorporateGroup.java
#Entity
#Table(name="corporate_group")
public class CorporateGroup extends BaseObject implements Serializable {
private Region region;
private Long id;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="id")
public Region getRegion() {
return region;
}
public void setRegion(Region region) {
this.region = region;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
} }
corporateGroupForm.jsp
<li>
<appfuse:label styleClass="desc" key="corporateGroupDetail.region"/>
<select name="regionDesc">
<option value=""><fmt:message key="select.pleaseSelect"/></option>
<c:forEach var="region" items="${regionsList}">
<c:set var="selected" value="${corporateGroup.region ne null and corporateGroup.region.regionDesc eq region.regionDesc}"/>
<option ${selected ? 'selected' : ''} value="${region.regionDesc }">${region.regionDesc } </option>
</c:forEach>
</select>
</li>
DB:
CREATE TABLE `corporate_group` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`comment` text,`name` varchar(255) NOT NULL,`parent_id`bigint(20) DEFAULT NULL,`primary_contact_id` bigint(20) DEFAULT NULL,`account_manager_email` varchar(255) DEFAULT NULL,`dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,`region_description` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`),KEY `FK61BCC225C8E0340A` (`parent_id`),KEY `FK61BC225F0655E4F` (`primary_contact_id`),KEY `FK_REGION_idx` (`region_description`),CONSTRAINT `fk_region` FOREIGN KEY (`region_description`) REFERENCES `region` (`region_description`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `FK61BC225F0655E4F` FOREIGN KEY (`primary_contact_id`) REFERENCES `app_user` (`id`),CONSTRAINT `FK61BCC225C8E0340A` FOREIGN KEY (`parent_id`) REFERENCES `corporate_group` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=843 DEFAULT CHARSET=latin1;
CREATE TABLE `region` (`id` bigint(20) NOT NULL,`country_code` varchar(50) NOT NULL,country_name` varchar(100) NOT NULL,`time_zone` varchar(100) NOT NULL,`region_description` varchar(255) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `description_UNIQUE` (`region_description`),KEY `id` (`id`),KEY `region_description` (`region_description`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Exception Stack Trace :
Hibernate: select corporateg0_.id as id2_,
corporateg0_.account_manager_email as account2_2_,
corporateg0_.comment as comment2_, corporateg0_.name as name2_,
corporateg0_.parent_id as parent6_2_, corporateg0_.primary_contact_id
as primary5_2_, corporateg0_.region_description as region7_2_ from
corporate_group corporateg0_ order by corporateg0_.name WARN
[http-bio-9080-exec-1] JDBCExceptionReporter.logExceptions(77) | SQL
Error: 0, SQLState: S1009 WARN [http-bio-9080-exec-1]
JDBCExceptionReporter.logExceptions(77) | SQL Error: 0, SQLState:
S1009 ERROR [http-bio-9080-exec-1]
JDBCExceptionReporter.logExceptions(78) | Invalid value for getLong()
- 'UK -UTC +0:00' ERROR [http-bio-9080-exec-1] JDBCExceptionReporter.logExceptions(78) | Invalid value for getLong()
- 'UK -UTC +0:00'
The error on the web page :
Data Access Failure
Hibernate operation: could not execute query; uncategorized SQLException for SQL [select corporateg0_.id as id2_, corporateg0_.account_manager_email as account2_2_, corporateg0_.comment as comment2_, corporateg0_.name as name2_, corporateg0_.parent_id as parent7_2_, corporateg0_.primary_contact_id as primary5_2_, corporateg0_.region_description as region6_2_ from corporate_group corporateg0_ order by corporateg0_.name]; SQL state [S1009]; error code [0]; Invalid value for getLong() - 'UK -UTC +0:00'; nested exception is java.sql.SQLException: Invalid value for getLong() - 'UK -UTC +0:00'
Region.java
#Entity
#Table(name = "region")
public class Region extends BaseObject implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String countryCode;
private String countryName;
private String timeZone;
private String regionDesc;
#Column(name="country_code",nullable=false)
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Column(name="country_name",nullable=false)
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
#Column(name="time_zone",nullable=false)
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
#Column(name="region_description",nullable=false)
public String getRegionDesc() {
return regionDesc;
}
public void setRegionDesc(String regionDesc) {
this.regionDesc = regionDesc;
}
#Override
public String toString() {
StringBuffer strBuff = new StringBuffer();
if (getId() != null) {
strBuff = strBuff.append("ID:" + getId() + ",");
strBuff = strBuff.append("Country Name:" + getCountryName() + ",");
strBuff = strBuff.append("Country Code:" + getCountryCode() + ",");
strBuff = strBuff.append("Timezone:" + getTimeZone() + ",");
strBuff = strBuff.append("Region Description:" + getRegionDesc() + ",");
}
return strBuff.toString();
}
#Override
public boolean equals(Object o) {
// TODO Auto-generated method stub
if (!(o instanceof Region)) {
return false;
}
Region reg = (Region) o;
return !(regionDesc != null ? !regionDesc.equals(reg.getRegionDesc()) : reg.getRegionDesc() != null);
}
#Override
public int hashCode() {
// TODO Auto-generated method stub
int hashcode = 0;
if (this.regionDesc != null) {
hashcode = hashcode + this.regionDesc.hashCode();
}
return hashcode;
}
}
Now a different error :
ERROR [localhost-startStop-1 ContextLoader.initWebApplicationContext(215) | Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_filterChainProxyPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext-dao.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext-dao.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.canvas8.model.CorporateGroup column: id (should be mapped with insert="false" update="false")
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:405)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:220)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:881)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:606)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:366)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1877)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
In your CorporateGroup entity class, you mapped region with region_description of Region entity which has a primary key of Long
#ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="region_description")
public Region getRegion() {
return region;
}
What you can do is you can map region member variable of CorporateGroup to primary key of Region entity class not the region_description.
Regarding this error :
Repeated column in mapping for entity:
com.canvas8.model.CorporateGroup column: id (should be mapped with
insert="false" update="false")
The error message is obvious, you have mapped same column twice. Refer this and fix the issue.
Hope this helps!
I was able to specify the referenced column name to resolve the issue for me. I didn't want to eager fetch the entities since it would only be used sometimes and didn't have permissions to modify the database schema.
Try this:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "region_description", referencedColumnName = "region_description")
private Region region;

Hibernate says non-existent column is unknown...obviously

Im starting to adapt my spring boot project to use jpa / hibernate. at this stage i simply want to retrieve the id of a table in mysql database.
Here are the relevant classes:
#SpringBootApplication
#ComponentScan(basePackages = {"rest.api.controller", "dao", rest.api.model", "rest.api.config"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner demo(PostRepository repository) {
return (args) -> {
// save a couple of customers
repository.findAll();
};
}
}
#Entity
#Table(name="post")
public class Post {
private String text;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name="id")
private long id;
#Column(name="sender_id")
private #JsonIgnore long senderId;
private #JsonIgnore long eventId;
private #JsonIgnore final String selectSql = " text, sender_id, event_id";
protected Post() {}
public Post(long id, float latitude, float longitude, Date created, String ip,
String text, long senderId, long eventId) {
this.text = text;
this.senderId = senderId;
this.eventId = eventId;
}
public Post(String text, long senderId, long eventId) {
this.text = text;
this.senderId = senderId;
this.eventId = eventId;
}
public String getText() {
return text;
}
public long getSenderId() {
return senderId;
}
public long getEventId() {
return eventId;
}
public void setId(long id) {
this.id = id;
}
}
public interface PostRepository extends CrudRepository<Post, Long> {
}
And mysql for the post table:
CREATE TABLE `post` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`text` varchar(4096) NOT NULL,
`sender_id` bigint(20) NOT NULL,
`event_id` bigint(20) DEFAULT NULL,
`created` datetime NOT NULL,
`ip` varchar(20) NOT NULL,
`latitude` float DEFAULT NULL,
`longitude` float DEFAULT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `post_sent_by_user` (`sender_id`),
CONSTRAINT `post_sent_by_user` FOREIGN KEY
I get the following error
2016-06-23 20:39:06.739 WARN 6895 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22
2016-06-23 20:39:06.740 ERROR 6895 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'post0_.select_sql' in 'field list'
2016-06-23 20:39:06.750 WARN 6895 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Warning Code: 1054, SQLState: 42S22
2016-06-23 20:39:06.751 WARN 6895 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'post0_.select_sql' in 'field list'
2016-06-23 20:39:06.770 ERROR 6895 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:790) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:777) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]
at rest.api.Application.main(Application.java:16) [main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) [idea_rt.jar:na]
Caused by: org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:242) ~[spring-orm-4.2.6.RELEASE.jar:4.2.6.RELEASE]
For the life of me, i cant work out why it is looking for a column with such a bizzare name as "post0_.select_sql" - doesnt seem at all related to my table or column.
I have googled arround for a while, but could not find anything to explain this.
Id be very grateful if somebody could help me here. (Im sure it should be simple as im not really attempting anything complex yet)
Thanks
Because you told Hibernate that your entity had a persistent field named that way:
private #JsonIgnore final String selectSql
I have no idea what this field is for and why it is in your entity, but it should probably be elsewhere, or at least defined as a constant (i.e. made static) or at the very least annotated by #Transient so that Hibernate knows it's not part of the persistent properties.

Could not insert Student record in database.(spring 3.0.5, mybatis3.0.3, mysql)

I have been trying to insert a Student record in mysql database, using spring 3 & mybatis3, but i am constantly getting following exception.
com.ibatis.common.jdbc.exception.NestedSQLException:
ERROR [stderr] (http-localhost/127.0.0.1:8080-4) --- The error occurred in /config/StudentMapper.xml.
ERROR [stderr] (http-localhost/127.0.0.1:8080-4) --- The error occurred while applying a parameter map.
ERROR [stderr] (http-localhost/127.0.0.1:8080-4) --- Check the insertStudent-InlineParameterMap.
ERROR [stderr] (http-localhost/127.0.0.1:8080-4) --- Check the statement (update failed).
ERROR [stderr] (http-localhost/127.0.0.1:8080-4) --- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'lastName)' at line 1
Please Help me resolve this exception.
sqlMapConfig.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<properties resource="/config/SqlMapConfigExample.properties"/>
<settings cacheModelsEnabled="true" enhancementEnabled="true"
useStatementNamespaces="false" />
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${username}" />
<property name="JDBC.Password" value="${password}" />
<property name="JDBC.DefaultAutoCommit" value="true"/>
</dataSource>
</transactionManager>
<sqlMap resource="/config/StudentMapper.xml" />
</sqlMapConfig>
My StudentMapper.xml-
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="com.fulcrum.mappers.StudentMapper">
<resultMap id="result" class="com.fulcrum.model.Student">
<result property="id" column="id" />
<result property="firstName" column="firstName" />
<result property="lastName" column="lastName" />
</resultMap>
<insert id="insertStudent" parameterClass="com.fulcrum.model.Student">
<![CDATA[
INSERT INTO student (firstName, lastName) VALUES (#firstName,#lastName);
]]>
<selectKey keyProperty="id" >
SELECT LAST_INSERT_ID() AS id
</selectKey>
</insert>
</sqlMap>
My insertStudentCode in daoimpl-
public void insertStudent(Student student) {
System.out.println("UserDaoImpl insertStudent()");
System.out.println("Student Name::" +student.getFirstName()+" "+student.getLastName());
/*New*/
String resource = "/config/SqlMapConfig.xml";
Reader reader;
try {
reader = Resources.getResourceAsReader (resource);
SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
System.out.println("SqlMap::::" +sqlMap);
// sqlMap.startTransaction();
sqlMap.insert("insertStudent", student);
// sqlMap.commitTransaction();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My Student Class Code-
package com.fulcrum.model;
public class Student {
private Long id;
private String firstName;
private String lastName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
I looked through some mybatis samples -
Shouldn't mybatis parameters be wrapped as - (#{id}, #{username}, #{password})
https://mybatis.github.io/mybatis-3/sqlmap-xml.html
Looks like the root cause of ur error from your stack trace is - 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 'lastName)' at line 1