Closed yujietan closed 1 year ago
Do not use this issue tracker to ask questions, instead use one of these channels. Questions will likely be closed without notice.
implementation(enforcedPlatform("io.quarkus:quarkus-universe-bom:3.1.2.Final")) implementation("io.quarkus:quarkus-kotlin") implementation("io.quarkus:quarkus-jackson") implementation("io.quarkus:quarkus-hibernate-reactive-panache") implementation("io.quarkus:quarkus-reactive-mysql-client") implementation("io.quarkus:quarkus-hibernate-validator") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.1") testImplementation("io.quarkus:quarkus-junit5")
https://github.com/quarkusio/quarkus/issues/34464
Unable to provide enterprise mariadb with maxscale to reproduce the issue
Hi , we tried building a reproducer but was not able to find any mariabdb image for 10.6.12-8 Enteprise
So we created the java and kotlin class required to replicate the issue
We did it using quarkus version 3.1.2.FINAL (tried with 2.16.6.FINAL the version we are using same error)
Sorrry for not uploading this as a reproducer project. Blocked by corporate network :(
Gradle Config
build.gradle
plugins { kotlin("jvm") id("java-library") id("io.quarkus") } allprojects { group = "com.trial.demo" version = "1.0.0-SNAPSHOT" } dependencies { implementation(enforcedPlatform("io.quarkus:quarkus-universe-bom:3.1.2.Final")) implementation("io.quarkus:quarkus-kotlin") implementation("io.quarkus:quarkus-jackson") implementation("io.quarkus:quarkus-hibernate-reactive-panache") implementation("io.quarkus:quarkus-reactive-mysql-client") implementation("io.quarkus:quarkus-hibernate-validator") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.1") testImplementation("io.quarkus:quarkus-junit5") }
Schema Files
CustomTable.java
package com.trial.demo.entities; import com.trial.demo.entities.mapper.HashMapConverter; import jakarta.persistence.*; import java.time.Instant; import java.util.Map; @Entity @Table(name = "custom_table", uniqueConstraints = {@UniqueConstraint(name = "UNIQUE_ACTION_MESSAGE", columnNames = {"two", "one", "ten"})}) public class CustomTable { public CustomTable() { } @Id @SequenceGenerator( name="custom_table_mock_seq", sequenceName = "custom_table_seq", allocationSize = 1 ) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "custom_table_mock_seq") private Long id; @Column(name = "one", updatable = false, nullable = false) private int one; @Column(name = "two", updatable = false, nullable = false) private String two; private String three; private String four; private String five; private String six; private Instant ten; private Instant zero; private int seven; private String eight; private String nine; @Convert(converter = HashMapConverter.class) private Map<String, String> eleven; public Long getId() { return id; } public int getOne() { return one; } public void setOne(int one) { this.one = one; } public String getThree() { return three; } public void setThree(String three) { this.three = three; } public String getFour() { return four; } public void setFour(String four) { this.four = four; } public String getFive() { return five; } public void setFive(String five) { this.five = five; } public String getSix() { return six; } public void setSix(String six) { this.six = six; } public Instant getTen() { return ten; } public void setTen(Instant ten) { this.ten = ten; } public Instant getZero() { return zero; } public void setZero(Instant zero) { this.zero = zero; } public int getSeven() { return seven; } public void setSeven(int seven) { this.seven = seven; } public String getEight() { return eight; } public void setEight(String eight) { this.eight = eight; } public String getNine() { return nine; } public void setNine(String nine) { this.nine = nine; } public Map<String, String> getEleven() { return eleven; } public void setEleven(Map<String, String> eleven) { this.eleven = eleven; } public String getTwo() { return two; } public void setTwo(String two) { this.two = two; } }
HashMapConverter.java
package com.trial.demo.entities.mapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.AttributeConverter; import java.util.Map; @ApplicationScoped public class HashMapConverter implements AttributeConverter<Map<String,String>, String> { @Override public String convertToDatabaseColumn(Map<String, String> attribute) { if(attribute == null){ return null; } String dataInDbFormat = null; ObjectMapper om = new ObjectMapper(); try{ dataInDbFormat = om.writeValueAsString(attribute); } catch (JsonProcessingException e) { e.printStackTrace(); } return dataInDbFormat; } @Override public Map<String, String> convertToEntityAttribute(String dbData) { if(dbData == null){ return null; } Map dataMap = null; ObjectMapper om = new ObjectMapper(); try{ dataMap = om.readValue(dbData, Map.class); } catch (JsonProcessingException e) { e.printStackTrace(); } return dataMap; } }
DAO Classes
CustomTableRepository.kt
package com.trial.demo import com.trial.demo.entities.CustomTable import io.quarkus.hibernate.reactive.panache.PanacheRepository import io.quarkus.hibernate.reactive.panache.common.runtime.ReactiveTransactional import io.smallrye.mutiny.Uni import jakarta.enterprise.context.ApplicationScoped @ApplicationScoped class CustomTableRepository : PanacheRepository<CustomTable> { companion object { fun String.toPanacheSQL(): String = "#$this" } @ReactiveTransactional internal fun addDataToMariaDb(data: List<CustomTable>): Uni<Void> { return this.persist(data) } }
Unit Test Class For Replicating the Issue
SqlErrorTest.java
package com.trial.demo import com.trial.demo.entities.CustomTable import io.quarkus.hibernate.reactive.panache.Panache import io.quarkus.hibernate.reactive.panache.Panache.flush import io.quarkus.test.junit.QuarkusTest import io.quarkus.vertx.VertxContextSupport import jakarta.inject.Inject import org.hibernate.reactive.mutiny.Mutiny.SessionFactory import org.junit.jupiter.api.Test import java.time.LocalDateTime import java.time.ZoneOffset @QuarkusTest class SqlErrorTest { @Inject lateinit var sessionFactory: SessionFactory @Inject lateinit var customTableRepository: CustomTableRepository fun generateTestData(): List<CustomTable> { var firstData = CustomTable() var secondData = CustomTable() firstData.one = 1 firstData.two = "HAPPY_2" firstData.three = "HAPPY_3" firstData.four = "HAPPY_4" firstData.five = "HAPPY_5" firstData.six = "HAPPY_6" firstData.seven = 0 firstData.eight = "HAPPY_8" firstData.nine = "HAPPY_9" firstData.ten = LocalDateTime.now().toInstant(ZoneOffset.UTC) firstData.zero = LocalDateTime.now().toInstant(ZoneOffset.UTC) firstData.eleven = mapOf( Pair("1", "1"), Pair("2", "2"), Pair("10","{\"\$aa-aa_aa_aa\":\"123\",\"\$bb-bb_bbb\":\"1a2b3c\",\"@cc-cc-8\":\"aaa_bbb_ccc=ddd\",\"@ee-ee_ee-3\":\"a[3]=ee_ee\",\"\$dd-dd\":\"1234\",\"\$ff-ff_aa\":\"-1\",\"\$gg-gg\":\"gtg\",\"@dd-dd-10\":\"ff_ff_ff_dd=6\",\"\$zz-be\":\"344.41\",\"\$hh-hh_hh\":\"1.1.0\",\"\$tt-yy\":\"16.77\",\"@pop-pp-3\":\"ff_dd_ff=/a/b/c\",\"@aa-aa-7\":\"aa_aa_aa=aa\",\"\$aa-aa_aa\":\"/aa/aa/aa/aa/aa/aa/aa.aa\",\"\$aar-aa\":\"1\",\"@aa-aal-2\":\"aa_aa=/aa/aa_aa\",\"\$aa-aa_aa\":\"1\",\"\$aa-aa_aa\":\"11\",\"\$aa-aa\":\"0\",\"@bb-bb-6\":\"bb_bb_bb=/bb/bb/bb\",\"\$br-bb_bbt\":\"0\",\"\$bb-bu_bbt\":\"1\",\"\$br-pbt_by\":\"0\",\"@bay-abr_mb-0\":\"bb\",\"\$bb-bb\":\"bb_bb\",\"@bby-bal-11\":\"bb_bb_bb=bb\",\"@bb-bb-5\":\"bb_bb_bb=/bb/bb_bb/bb\",\"@bb-bb-4\":\"bb_bb_bb=/bb/bb/bb\",\"@array-global-1\":\"bb=bb\",\"\$bbr-bbd_bb\":\"bb\",\"\$bb-bb_bb\":\"bb-bb_bb-133abc-123\",\"@bb-bb_bb-2\":\"bb[2]=bb\",\"\$bb-bbl_bb_bb\":\"0\",\"\$bb-bb_bb\":\"bb\",\"@bb-bb-0\":\"bbL\",\"\$bb-bb_bbb\":\"0\",\"\$bb-bb\":\"bb\",\"\$bb-bb_bb\":\"0\",\"\$bb\":\"21\",\"@bb-bb_bb-1\":\"bb[1]=bb\",\"\$bb-bbb_bbb\":\"0\",\"\$bbb-bb\":\"b\",\"\$bb-bb_bb\":\"134\",\"\$gg-gge_lg\":\"0\",\"\$ggr-gt\":\"62cac\",\"@gg-gggl-9\":\"gg_gg_gg=gg\",\"\$gg-gg_gg\":\"0\",\"\$gg-egg_ggd\":\"/gg/gg/gg\"}") ) secondData.one = 2 secondData.two = "HAPPY_2" secondData.three = "HAPPY_3" secondData.four = "HAPPY_4" secondData.five = "HAPPY_5" secondData.six = "HAPPY_6" secondData.seven = 1 secondData.eight = "HAPPY_8" secondData.nine = "HAPPY_9" secondData.ten = LocalDateTime.now().toInstant(ZoneOffset.UTC) secondData.zero = LocalDateTime.now().toInstant(ZoneOffset.UTC) secondData.eleven = mapOf( Pair("3", "3"), Pair("4", "4"), Pair("5", "!@#$%^&*()_"), Pair("6", "=-098~\"765`432") ) return mutableListOf(firstData, secondData) } /** * Test Will Fail Due To SQL Syntax Error */ @Test fun addDataWithStatelessTransaction_1() { var listToAdd = generateTestData() sessionFactory.withStatelessTransaction { session -> session.insertAll(*listToAdd.toTypedArray()) }.await().indefinitely() } /** * Test Will Fail Due To SQL Syntax Error */ @Test fun addDataWithStatelessTransaction_2() { var listToAdd = generateTestData() sessionFactory.withStatelessSession { session -> session.withTransaction { tx -> tx.markForRollback() session.insertAll(*listToAdd.toTypedArray()) } }.await().indefinitely() } /** * Test Will Pass Because No Transaction Is Used */ @Test fun addDataWithoutTransaction() { var listToAdd = generateTestData() sessionFactory.withStatelessSession { session -> session.insertAll(*listToAdd.toTypedArray()) }.await().indefinitely() } /** * Test Will Fail Due To SQL Syntax Error */ @Test fun addDataUsingPanache(){ var listToAdd = generateTestData() VertxContextSupport.subscribeAndAwait { Panache.withTransaction { customTableRepository.persist(listToAdd) } } } /** * Test Will Pass Because No Transaction Is Used */ @Test fun addDataUsingPanacheWithoutTransaction(){ var listToAdd = generateTestData() listToAdd[0].two = "SAD" listToAdd[1].two = "SAD" VertxContextSupport.subscribeAndAwait { Panache.withSession { customTableRepository.persist(listToAdd).flatMap { flush() } } } } }
DB Table DDL
CREATE SEQUENCE custom_table_seq START WITH 1 INCREMENT BY 1 NOCYCLE; CREATE TABLE `custom_table` ( `id` bigint(20) NOT NULL DEFAULT nextval(`custom_table_seq`), `one` int(11) unsigned NOT NULL, `two` varchar(50) NOT NULL, `three` varchar(100) DEFAULT NULL, `four` varchar(100) DEFAULT NULL, `five` text DEFAULT NULL, `six` varchar(100) DEFAULT NULL, `ten` datetime DEFAULT NULL, `zero` datetime DEFAULT NULL, `seven` int(11) DEFAULT NULL, `eight` varchar(30) DEFAULT NULL, `nine` varchar(30) DEFAULT NULL, `eleven` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `UNIQUE_ACTION_MESSAGE` (`one`,`two`,`ten`), KEY `idx_env` (`one`) USING BTREE, KEY `idx_startTime_desc` (`ten`) USING BTREE )
Hi closing issue. Turns out the db server config is different. The one where is not working has ANSI_QUOTES enabled.. Thus failing with syntax error when inserting
Thank you for letting us know
Questions
Do not use this issue tracker to ask questions, instead use one of these channels. Questions will likely be closed without notice.
Version
Context
https://github.com/quarkusio/quarkus/issues/34464
Do you have a reproducer?
Unable to provide enterprise mariadb with maxscale to reproduce the issue
Steps to reproduce
Hi , we tried building a reproducer but was not able to find any mariabdb image for 10.6.12-8 Enteprise
So we created the java and kotlin class required to replicate the issue
We did it using quarkus version 3.1.2.FINAL (tried with 2.16.6.FINAL the version we are using same error)
Sorrry for not uploading this as a reproducer project. Blocked by corporate network :(
Gradle Config
build.gradle
Schema Files
CustomTable.java
HashMapConverter.java
DAO Classes
CustomTableRepository.kt
Unit Test Class For Replicating the Issue
SqlErrorTest.java
DB Table DDL
Extra