I am getting this warn when I try to start my spring boot application:
2018-09-30 07:34:23.097 INFO 59360 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Hibernate: create table social_link (author_username varchar(255) not null, type varchar(255) not null, value varchar(255), primary key (author_username, type)) engine=MyISAM
2018-09-30 07:34:24.067 WARN 59360 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
Strange thing is that I can execute SQL statement via the SQL workbench without a problem and everything works fine after that.
Here is the entity that is responsible for that table:
#Entity
public class SocialLink {
#EmbeddedId
private SocialLinkKeyEmbeddable id = new SocialLinkKeyEmbeddable();
private String value;
#ManyToOne
#MapsId("author_username")
#JoinColumns({
#JoinColumn(name="author_username", referencedColumnName="author_username")
})
private Author author;
//Getters and setters
}
#Embeddable
public class SocialLinkKeyEmbeddable implements Serializable {
#Column(name = "author_username")
private String author_username;
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAuthor_username() {
return author_username;
}
public void setAuthor_username(String author_username) {
this.author_username = author_username;
}
#Override
public int hashCode() {
return super.hashCode();
}
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
public interface SocialLinkRepository extends CrudRepository<SocialLink, SocialLinkKeyEmbeddable> {
}
The problem was with the length of the key. MySQL was pretending it is larger than 1000 bytes. It seems its a common problem with MyISAM storage engine.
In order to fix it I added:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect
to my applicaiton.properties and now the problem is fixed.
Was using this post as reference
#1071 - Specified key was too long; max key length is 1000 bytes
I had a similar problem caused by spring.jpa.database-platform property set to MySQL5Dialect.
Setting the property to MySQL8Dialect or removing it altogether (which enables auto-configuration) solved the problem.
I added a column length to my ID field to prevent the varchar(255) default.
#Entity
public class MyEntity {
#Id
#Column(length = 64)
private String id;
...
}
For those who are only using Hibernate (not Spring), edit the SQL dialect property from hibernate.cfg.xml file, located in src/main/resources folder.
<property name="dialect">org.hibernate.dialect.MySQL55Dialect</property>
Or remove the dialect property altogether.
Error-Caused by: java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 1000 bytes
operation perform- #Id private String userName;
Solution
step1-Go to mysql database--> step2-Go to schema setting -->step3-change Default charset to latin1--> step 4-Run on server your spring mvc program--> step 5- Finally Your table is created with #Id on String
I had the same issue. I resolved it by assigning char set to my database on creation:
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb3;
Related
I want to create new table on my database using this class
#Entity
#Table(name = "currency_rate")
public class CurrencyRate {
#Id
private String id;
#Column(name = "source_currency")
private String sourceCurrency;
#Column(name = "target_currency")
private String targetCurrency;
#Column(name = "exchange_rate")
private double exchangeRate;
#Column
private Date date;
#PrePersist
public void generateID() {
this.id = this.date.toString().replace("-", "") + sourceCurrency + targetCurrency;
}
//getters, setters
}
When I try to run my application with property
spring.jpa.hibernate.ddl-auto=create
I got this exception
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Specified key was too long; max key length is 1000 bytes
Looks like I can't use Spring as my ID? Changing type to Long solves problem, but I really wanted to go with String with this one. From what I searched, it should be totally doable.
As per tutorial from https://www.tutorialspoint.com/hibernate/hibernate_annotations.htm, the attribute can be defined by Column annotation in details.
#Column Annotation The #Column annotation is used to specify the
details of the column to which a field or property will be mapped. You
can use column annotation with the following most commonly used
attributes −
name attribute permits the name of the column to be explicitly
specified.
length attribute permits the size of the column used to map a value
particularly for a String value.
nullable attribute permits the column to be marked NOT NULL when the
schema is generated.
unique attribute permits the column to be marked as containing only
unique values.
What matters here for your question is length parameter, maybe you can try annotate your id like below:
#Id
#Column(length = 100)
private String id;
Framework Spring MVC 4.x
Hibernate 4.x
Jackson 2.8
I have two columns one is publishDate and createdDate. Publish date user need to manually enter it. Created date in MySQL column has a default set as CURRENT_TIMESTAMP, so when an entry is created DB will automatically timestamp the entry.
I have a book POJO publishDate and createdDate field... publishDate can handle null data for some reason. But Timestamp field gets an exception. Why is this?
org.springframework.http.converter.HttpMessageNotWritableException: Could not
write content: (was java.lang.NullPointerException) (through reference chain:
java.util.HashMap["results"]->java.util.ArrayList[30]-
>com.app.books.Book["dateCreated"]); nested exception is
com.fasterxml.jackson.databind.JsonMappingException: (was
java.lang.NullPointerException) (through reference chain:
java.util.HashMap["results"]->java.util.ArrayList[30]-
>com.app.books.Book["dateCreated"])
I tried to suppress this by adding annotation, I tried several of them because I keep reading conflicting info on the comments section on which to use.
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // but show JsonSerialize is deprecated
#JsonInclude(Include.NON_NULL)// Include can not be resolved as variable
#JsonInclude(JsonInclude.Include.NON_DEFAULT) // finally doesn't give me an error but I still get the same exception.
This is my book Class
#Entity
#Table(name="books")
#Component
public class Book implements Serializable{
/**
*
*/
private static final long serialVersionUID = -2042607611480064259L;
#Id
#GeneratedValue
private int id;
#NotBlank
private String name;
#NotBlank
#Size(min=2, max=16)
private String ispn;
#DecimalMin(value = "0.1")
private double price;
//#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
//#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
//#JsonIgnoreProperties(ignoreUnknown = true)
#JsonInclude(JsonInclude.Include.NON_DEFAULT)
private Timestamp dateCreated;
private Date datePublished;
Very wried... Thanks for helping..
You may have better results switching from primitives (int & double) to Java classes (Int & Double) in your Book class. See JsonMappingException (was java.lang.NullPointerException) also JSON: JsonMappingException while try to deserialize object with null values
I am very new in Hibernate. I am using Hibernate with JPA. I have an annotated entity class and a table related to that entity class.
#Entity
public class Test implements Serializable {
#Id
#GenericGenerator(name="inc" , strategy="identity")
#GeneratedValue(generator="inc")
private int id;
private String address; // setter getter and constructor
}
When saving this entity, it insert the data into the db. But during application running process another application is inserting data into same table. when my application try to save the data then Duplicate entry '59' for key 'PRIMARY' exception generated. So I want to use a generator which can insert the data and generate id in database level rather than application level and the identifier must saved back to my entity.
Use the Table generator strategy or the sequence generator.
You do not have to specify a generator. You can use the default generator and never set the id manually. If the error still comes post your merge/persist method.
More informations about generators can you found here https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing
#Entity
public class Test implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String address; // setter getter and constructor
}
I'm trying to implement some kind of "poll system" on my web based on Spring MVC + MySQL. The problem I'm having is that I have 2 classes I'm trying to map. One is the DTO which I use to move the data through the web, and the other one is the one I use to access the database with Hibernate. So far, so good.
The idea I'm trying to implement is having a few Lists on the DTO, transform them into a JSON and afterwards saving them on the database (as a String).
Now, in order to map these 2 objects I'm using an Orika Custom Map. The funny thing that happens to me is that I'm able to save the lists I have into the database as JSON (I'm using GSON to convert them), but when I need them back, Orika throws and exception.
I'll try now to put my code as clear as possible to see if someone can help me. As I'm telling you, when the time comes to save the data, I have no problem at all, but when I need to get it out (getting the string, parsing it to a JSON and afterwards to a List), it collapses. Any ideas?? Thanks in advance
ORIKA MAPPING
mapperFactory.classMap(EncuestaDTO.class, Encuesta.class).mapNulls(false).byDefault().customize(new CustomMapper<EncuestaDTO, Encuesta>(){
#Override
public void mapAtoB(EncuestaDTO a, Encuesta b, MappingContext context){
Type listTypeString = new TypeToken<List<String>>(){}.getType();
/************ Respuestas */
String respuestas = new Gson().toJson(a.getRespuestas(), listTypeString);
b.setRespuestas(respuestas);
}
#Override
#SuppressWarnings("unchecked")
public void mapBtoA(Encuesta b, EncuestaDTO a, MappingContext context){
Type listTypeString = new TypeToken<List<String>>(){}.getType();
/************ Respuestas */
List<String> respuestas = new Gson().fromJson(b.getRespuestas(), listTypeString);
a.setRespuestas(respuestas);
}
}).register();
Encuesta
#Id
#Column(name = "idEncuesta", unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idEncuesta;
#Column(name = "idCreador", nullable = false)
private Long idCreador;
#Column(name = "pregunta")
private String pregunta;
#Column(name = "respuestas")
private String respuestas;
#Column(name = "numRespuestas")
private Long numRespuestas;
#Column(name = "fechaCreacion")
private Date fechaCreacion;
#Column(name = "fechaFin")
private Date fechaFin;
#Column(name = "oficial")
private boolean oficial;
EncuestaDTO
private Long idEncuesta;
private Long idCreador;
private String pregunta;
private List<String> respuestas;
private Long numRespuestas;
private Date fechaCreacion;
private Date fechaFin;
private boolean oficial;
MANAGER
#Override
public void aniadirEncuesta(EncuestaDTO encuestaDTO) {
encuestaRepositorio.aniadirEncuesta(mapper.map(encuestaDTO, Encuesta.class));
}
#Override
public List<EncuestaDTO> getListaEncuestas() {
List<Encuesta> listaEncuesta = (List<Encuesta>) encuestaRepositorio.getListaEncuestas();
return mapper.mapAsList(listaEncuesta, EncuestaDTO.class); // HERE I GET THE ERROR
}
EXCEPTION
GRAVE: El Servlet.service() para el servlet [appServlet] en el contexto con ruta [/myApp] lanzó la excepción [Request processing failed; nested exception is ma.glasnost.orika.MappingException: While attempting the folling mapping:
sourceType = String
destinationType = ArrayList<String>
Error occurred: ma.glasnost.orika.MappingException: While attempting the folling mapping:
sourceType = ArrayList<String>
sourceProperty = 1(String)
destinationType = String
destinationProperty = bytes(byte[])
Error occurred: java.lang.IllegalArgumentException: Attempt was made to generate assignment/setter code for [destination.bytes(byte[])] which has no setter/assignment method] con causa raíz
java.lang.IllegalArgumentException: Attempt was made to generate assignment/setter code for [destination.bytes(byte[])] which has no setter/assignment method
at ma.glasnost.orika.impl.generator.VariableRef.assign(VariableRef.java:223)
at ma.glasnost.orika.impl.generator.specification.ObjectToObject.generateMappingCode(ObjectToObject.java:23)
at ma.glasnost.orika.impl.generator.SourceCodeContext.mapFields(SourceCodeContext.java:644)
at ma.glasnost.orika.impl.generator.MapperGenerator.generateFieldMapCode(MapperGenerator.java:252)
at ma.glasnost.orika.impl.generator.MapperGenerator.addMapMethod(MapperGenerator.java:172)
at ma.glasnost.orika.impl.generator.MapperGenerator.build(MapperGenerator.java:72)
at ma.glasnost.orika.impl.DefaultMapperFactory.buildMapper(DefaultMapperFactory.java:1046)
at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:614)
at ma.glasnost.orika.impl.DefaultMapperFactory.lookupMapper(DefaultMapperFactory.java:581)
at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMapper(MapperFacadeImpl.java:523)
at ma.glasnost.orika.impl.MapperFacadeImpl.resolveMappingStrategy(MapperFacadeImpl.java:203)
at ma.glasnost.orika.impl.DefaultBoundMapperFacade$BoundStrategyCache.getStrategy(DefaultBoundMapperFacade.java:253)
at ma.glasnost.orika.impl.DefaultBoundMapperFacade.map(DefaultBoundMapperFacade.java:136)
at ma.glasnost.orika.generated.Orika_Encuesta_EncuestaDTO_Mapper137715823.mapBtoA(Orika_Encuesta_EncuestaDTO_Mapper137715823.java)
at ma.glasnost.orika.impl.ReversedMapper.mapAtoB(ReversedMapper.java:65)
at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy$ForwardMapperReference.map(UseCustomMapperStrategy.java:74)
at ma.glasnost.orika.impl.mapping.strategy.UseCustomMapperStrategy.map(UseCustomMapperStrategy.java:50)
at ma.glasnost.orika.impl.MapperFacadeImpl.mapAsCollection(MapperFacadeImpl.java:633)
at ma.glasnost.orika.impl.MapperFacadeImpl.mapAsList(MapperFacadeImpl.java:386)
at ma.glasnost.orika.impl.MapperFacadeImpl.mapAsList(MapperFacadeImpl.java:716)
at ma.glasnost.orika.impl.ConfigurableMapper.mapAsList(ConfigurableMapper.java:180)
MySQL TABLE
CREATE TABLE `encuestas` (
`idEncuesta` int(11) NOT NULL AUTO_INCREMENT,
`idCreador` int(11) NOT NULL,
`pregunta` longtext,
`respuestas` longtext,
`numRespuestas` int(11) DEFAULT NULL,
`fechaCreacion` datetime DEFAULT NULL,
`fechaFin` datetime DEFAULT NULL,
`oficial` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`idEncuesta`),
UNIQUE KEY `idEncuesta_UNIQUE` (`idEncuesta`),
KEY `idCreador_idx` (`idCreador`),
CONSTRAINT `idCreador` FOREIGN KEY (`idCreador`) REFERENCES `usuarios` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
OK, I finally got it. The problem was that Orika tried to map it byDefault and, afterwards, tried to do the custom mapping. That meant that it crashed as it didn't know how to map it by default.
By adding and ".exclude("respuestas")" and later on configure the mapping manually (as shown in the code), I got everything mapped just as I wanted. In terms of code, it would be like this:
mapperFactory.classMap(EncuestaDTO.class, Encuesta.class).mapNulls(false).exclude("respuestas").byDefault().customize(new CustomMapper<EncuestaDTO, Encuesta>()
I need to store some data in a MySQL-database using Jpa 2/Hibernate 3.5.1. For legacy reasons the table I want to store data in has a compound primary key. The first part of the primary key is of type INTEGER (auto-increment-value), the second part is of type BIGINT (Long in Java-code - to be set manually before persisting).
I have implemented (example code below the stacktrace) the combined primary key via the #IdClass-Annotation, the first-key-part also has a generation strategy set: #GeneratedValue(strategy = GenerationType.IDENTITY)
When trying to persist an object with code like this
...
TestData testData = new TestData("data");
testData.setIdPartTwo(2L);
entityManager.getTransaction().begin();
entityManager.persist(testData);
entityManager.getTransaction().commit();
the following exception is thrown:
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of org.example.persistence.TestDataId.idPartOne
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1174)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:674)
at org.example.persistence.PersistenceTest.shouldPersistTestData(PersistenceTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:640)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:627)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:799)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1103)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:137)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:121)
at org.testng.TestRunner.runWorkers(TestRunner.java:1098)
at org.testng.TestRunner.privateRun(TestRunner.java:727)
at org.testng.TestRunner.run(TestRunner.java:581)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:315)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:310)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:272)
at org.testng.SuiteRunner.run(SuiteRunner.java:221)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:40)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:83)
at org.testng.internal.thread.ThreadUtil$CountDownLatchedRunnable.run(ThreadUtil.java:151)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of org.example.persistence.TestDataId.idPartOne
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:151)
at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:438)
at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:122)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:800)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:778)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:668)
... 24 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field org.example.persistence.TestDataId.idPartOne to org.hibernate.id.IdentifierGeneratorHelper$2
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:139)
... 35 more
My entity-class looks like this:
#Entity
#IdClass(TestDataId.class)
public class TestData implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idPartOne;
#Id
private Long idPartTwo;
private String data;
public TestData() {}
// getters and setters
// hashCode() and equals()
}
The combined-primary-key:
public class TestDataId implements Serializable {
private static final long serialVersionUID = 1L;
private Integer idPartOne;
private Long idPartTwo;
public TestDataId() {}
// getters and setters
// hashCode() and equals()
}
Test-Table was created with the following statement:
CREATE TABLE `testdb`.`testdata`
(`idPartOne` INTEGER NOT NULL AUTO_INCREMENT,
`idPartTwo` BIGINT(20) NOT NULL DEFAULT 0,
`data` VARCHAR(45),
PRIMARY KEY(`idPartOne`, `idPartTwo`))
ENGINE = InnoDB;
Changing the GenerationType to TABLE would make it work, but would generate idPartOne-values in steps of ~32.000. Unfortunately, another application uses this very same database-table without JPA/Hibernate and is nicely incrementing this id-part in steps of 1.
It is required that the id-generation is done in the same way no matter which application stores data into this table (that is, id incrementing of 1). What would be the best solution to achieve this? Hint, we cannot change the other application!
Any help is really appreciated.
Thx,
Markus
Does it work when you annotate the embedded id?
#Embeddable
public class TestDataId
{
#GeneratedValue(strategy = GenerationType.TABLE)
private Integer idPartOne;
private Long idPartTwo;
}
#Entity
public class TestData
{
#EmbeddedId
private TestDataId key;
private String data;
}