मेरे पास h2 डेटाबेस के साथ स्प्रिंग बूट प्रोजेक्ट है। एक टेबल debug को schema.sql से इनिशियलाइज़ किया जाता है:

DROP TABLE IF EXISTS debug;
  
CREATE TABLE debug (
  id BIGINT PRIMARY KEY,
  dummycol VARCHAR(250) NOT NULL
);

data.sql:

INSERT INTO debug (id, dummycol) VALUES
  (0, 'foo'), 
  (1, 'ba');

उसके लिए काम करने के लिए मुझे application.properties में spring.jpa.hibernate.ddl-auto=none डालना होगा। दस्तावेज़ीकरण यह schema.sql के लिए आवश्यक है, लेकिन मैंने पाया कि स्कीमा उत्पन्न होने के दौरान create-drop जैसे अन्य मान के साथ (मुझे एनोटेट कक्षाओं से लगता है) लोडिंग स्क्रिप्ट data.sql पर ध्यान नहीं दिया जाता है, इसलिए स्टार्टअप के बाद टेबल खाली हैं।

मैं एक इकाई वर्ग को परिभाषित करता हूं:

@Entity
@Table(name = "debug")
@Data
@NoArgsConstructor
public class DebugE {

    @Id
    //@GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="id")
    private Long id;

    @Column(name="dummycol")
    private String dummy;
}

फिर, मैं CrudRepository: public interface DebugRepository extends CrudRepository<DebugE, Long> को उपवर्गित करता हूं और तालिका में एक इकाई ऑब्जेक्ट जोड़ता हूं

@Autowired
DebugRepository cr;
...
    DebugE d = new DebugE();
    d.setId(computeFreeId(cr))
    d.setDummy("foo1");
    cr.save(d);

अब तक सब कुछ काम करता है, लेकिन अब मैं id को स्वचालित रूप से सेट करना चाहता हूं। उसके लिए मैं कक्षा में @GeneratedValue जोड़ता हूं और टिप्पणी करता हूं d.setId क्योंकि मुझे उम्मीद है कि ढांचा मेरे लिए ऐसा करेगा। GenerationType के प्रति मेरी कोई प्राथमिकता नहीं है, अब तक न तो काम करता है:
AUTO,SEQUENCE:

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 90036, SQLState: 90036
o.h.engine.jdbc.spi.SqlExceptionHelper   : Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]
o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [call next value for hibernate_sequence]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement] with root cause

org.h2.jdbc.JdbcSQLSyntaxErrorException: Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:576) ~[h2-1.4.200.jar:1.4.200]

IDENTITY:

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 23502, SQLState: 23502
o.h.engine.jdbc.spi.SqlExceptionHelper   : NULL not allowed for column "ID"; SQL statement:
insert into debug (id, dummycol) values (null, ?) [23502-200]
o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ID"; SQL statement:
insert into debug (id, dummycol) values (null, ?) [23502-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:459) ~[h2-1.4.200.jar:1.4.200]

TABLE:

 o.hibernate.id.enhanced.TableGenerator   : HHH000351: Could not read or init a hi value

org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "HIBERNATE_SEQUENCES" not found; SQL statement:
select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update [42102-200]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:453) ~[h2-1.4.200.jar:1.4.200]

अन्य प्रश्नों पर आधारित प्रयास:

  • https://stackoverflow.com/a/39094773 strategy=GenerationType.IDENTITY और hibernate.dialect=org.hibernate.dialect.H2Dialect को application.properties में जोड़ना। चेतावनी देता है: 'hibernate.dialect' is an unknown property. और त्रुटि संदेश में कोई बदलाव नहीं
  • https://stackoverflow.com/a/63775719/3014199 spring.jpa.hibernate.use-new-id-generator-mappings=false
    . जोड़ना IDENTITY,SEQUENCE के लिए कोई बदलाव नहीं। TABLE के लिए समान त्रुटि:
org.hibernate.orm.deprecation            : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead.  See Hibernate Domain Model Mapping Guide for details.
o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 42102, SQLState: 42S02
o.h.engine.jdbc.spi.SqlExceptionHelper   : Table "HIBERNATE_SEQUENCES" not found; SQL statement:
select sequence_next_hi_value from hibernate_sequences where sequence_name = 'debug' for update [42102-200]
  • https://stackoverflow.com/a/63127119/3014199
    spring.jpa.hibernate.ddl-auto को none से create-drop पर सेट करना काम करता है (अर्थात आईडी उत्पन्न होती है, पंक्तियों को तालिका में जोड़ा जाता है) लेकिन अब तालिका को data.sql से प्रारंभ नहीं किया गया है।

अतिरिक्त जानकारिया

application.properties:

spring.datasource.url=jdbc:h2:mem:h2db
spring.h2.console.enabled=true
spring.h2.console.path=/h2

#spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.initialization-mode=embedded
#hibernate.dialect=org.hibernate.dialect.H2Dialect
#spring.jpa.hibernate.use-new-id-generator-mappings=false

build.gradle:

plugins {
    id 'org.springframework.boot' version '2.3.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
    id 'java'
    id "io.freefair.lombok" version "5.2.1"
}


group = 'com.my.project'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    runtimeOnly 'com.h2database:h2'
}

समाधान

spring.jpa.hibernate.ddl-auto=none application.properties
. में @GeneratedValue(strategy=GenerationType.IDENTITY) कक्षा में और id BIGINT PRIMARY KEY AUTO_INCREMENT में schema.sql ने इसे काम किया।

0
peer 12 सितंबर 2020, 22:11

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप आईडी उत्पन्न करना चाहते हैं और साथ ही * sql फाइलों का उपयोग करना चाहते हैं, तो आपको निर्माण तालिका में अपने आईडी फ़ील्ड में auto_increment संपत्ति को परिभाषित करने की आवश्यकता है।

क्योंकि जब आप पीढ़ी की रणनीति का उपयोग करते हैं - पहचान, हाइबरनेट का मानना ​​​​है कि आपके कॉलम एक टेबल साइड पर ऑटो इंक्रीमेंट हैं।

1
Vielen Danke 14 सितंबर 2020, 21:28