Set<Enum> von Hibernate Entity als ENUM(...)ARRAY in der H2-Datenbank speichern

ExceptionOfExpectation

Bekanntes Mitglied
Hallo,
ich habe folgendes Problem in meinem Projekt:
H2 Datenbank kann mit den Set-Kollektion nicht umgehen, ich habe in meiner Tabelle eine Zeile mit ENUM ARRAY
tree_empty.gif
CHARACTERISTIC : ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY
Dazu habe ich die Entity Klasse & Enum:
Java:
@Entity
@Data
@Access(AccessType.FIELD)
public class ProductObject {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @SequenceGenerator(
            name = "product_seq_gen",
            sequenceName = "PRODUCT_SEQUENCE",
            allocationSize = 1
        )
    private Long id;
    
    @Column(name="foodId")
    private Long foodId;
    
    @Column(name="puppyId")
    private Long puppyId;
    
    @Column(name="name")
    private String name;
    
    @Column(name="weight", length=30)
    private BigDecimal weight;
    
    @Column(name="price")
    private BigDecimal price;
    
    @Column(name="image")
    private String image;
    

    @Column(name="object_name")
    private String objectName;
    
    @Enumerated(EnumType.STRING)
    private FoodType foodType;
    
    
    
    @Column(name="color")
    private String color;
    
    private int count;
    
    @OneToOne(mappedBy="productObject", cascade=CascadeType.ALL, fetch= FetchType.EAGER)
    private Bread race;
    
    
    
    @Enumerated(EnumType.STRING)
    @Column(name = "characteristic")
    private Set<AnimalCharacter> characteristic;

    @Column(name="height", length=50)
    private BigDecimal height;

    
    @ManyToOne
    @JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
    private Category category;
    

    @Override
    public int hashCode() {
         return Objects.hash(id, puppyId, name, weight, price, image, objectName, foodType, characteristic, color, count, race, height, category);  // Hier nur id und andere stabile Eigenschaften verwenden
    }
    
    public enum FoodType{    MEAT, LEFTOVER_FOOD, CANNED, PRODUCTION, VITAMINS, BONE, DRINKS, LIQUID_FOOD, NONE    }
    
    
    

}
Die AnimalCharacter Klasse:

Code:
package de.irahi.welp.props;



public enum AnimalCharacter{
    Calm("Calm"),
    Vigorous("Vigorous"),
    Fearful("Fearful"),
    Friendly("Friendly"),
    Independent("Independent"),
    Reasonable("Reasonable"),
    Loyal("Loyal"),
    None("None"),
    Playful("Playful"),
    Protective("Protective"),
    Curious("Curious"),
    Social("Social"),
    Aggressive("Aggressive");

    
    private final String characterName;
    
    AnimalCharacter(String characterName){
        this.characterName = characterName;
    }
    
    public String getCharacterName() {    return this.characterName;    }
    
}
Bei dem Versuch das Entity Objekt zuspeichern bekomme ich folgende Fehlermeldung:

XML:
2024-11-21T17:29:09.271+01:00 DEBUG 7608 --- [Puppies] [nio-8080-exec-9] org.hibernate.SQL                        :
    insert
    into
        product_object
        (category_id, characteristic, color, count, food_id, food_type, height, image, name, object_name, price, puppy_id, weight, id)
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, default)
Hibernate:
    insert
    into
        product_object
        (category_id, characteristic, color, count, food_id, food_type, height, image, name, object_name, price, puppy_id, weight, id)
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, default)
2024-11-21T17:29:09.359+01:00  WARN 7608 --- [Puppies] [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 22018, SQLState: 22018
2024-11-21T17:29:09.360+01:00 ERROR 7608 --- [Puppies] [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper   : Datenumwandlungsfehler beim Umwandeln von "ARRAY [CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740007437572696f7573' AS JAVA_OBJECT), CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740008467269656e646c79' AS JAVA_OBJECT)] (PRODUCT_OBJECT: ""CHARACTERISTIC"" ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY)"
Data conversion error converting "ARRAY [CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740007437572696f7573' AS JAVA_OBJECT), CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740008467269656e646c79' AS JAVA_OBJECT)] (PRODUCT_OBJECT: ""CHARACTERISTIC"" ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY)"; SQL statement:
insert into product_object (category_id,characteristic,color,count,food_id,food_type,height,image,name,object_name,price,puppy_id,weight,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,default) [22018-224]
2024-11-21T17:29:09.389+01:00 ERROR 7608 --- [Puppies] [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement [Datenumwandlungsfehler beim Umwandeln von "ARRAY [CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740007437572696f7573' AS JAVA_OBJECT), CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740008467269656e646c79' AS JAVA_OBJECT)] (PRODUCT_OBJECT: ""CHARACTERISTIC"" ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY)"
Data conversion error converting "ARRAY [CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740007437572696f7573' AS JAVA_OBJECT), CAST(X'aced00057e72002364652e69726168692e77656c702e70726f70732e416e696d616c43686172616374657200000000000000001200007872000e6a6176612e6c616e672e456e756d00000000000000001200007870740008467269656e646c79' AS JAVA_OBJECT)] (PRODUCT_OBJECT: ""CHARACTERISTIC"" ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY)"; SQL statement:
insert into product_object (category_id,characteristic,color,count,food_id,food_type,height,image,name,object_name,price,puppy_id,weight,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,default) [22018-224]] [insert into product_object (category_id,characteristic,color,count,food_id,food_type,height,image,name,object_name,price,puppy_id,weight,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,default)]; SQL [insert into product_object (category_id,characteristic,color,count,food_id,food_type,height,image,name,object_name,price,puppy_id,weight,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?,default)]] with root cause

org.h2.jdbc.JdbcSQLDataException: Datenumwandlungsfehler beim Umwandeln von "JAVA_OBJECT to ENUM"
Data conversion error converting "JAVA_OBJECT to ENUM" [22018-224]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:518) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:489) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.message.DbException.get(DbException.java:223) ~[h2-2.2.224.jar:2.2.224]
    at org.h2.message.DbException.get(DbException.java:199) ~[h2-2.2.224.jar:2.2.224]
____________________________________________________________________________________________________________________________________________
ich habe bereits versucht mit einer Konverter Klasse zum Laufen zu bringen:

Java:
@Converter
public class AnimalCharacterSetConverter implements AttributeConverter<Set<AnimalCharacter>, String> {

    @Override
    public String convertToDatabaseColumn(Set<AnimalCharacter> attribute) {
        
        return attribute.stream().map(Enum::name).collect(Collectors.joining(","));
    }

    @Override
    public Set<AnimalCharacter> convertToEntityAttribute(String dbData) {
        // TODO Auto-generated method stub
        return Arrays.stream(dbData.split(",")).map(AnimalCharacter::valueOf)
                .collect(Collectors.toSet());
    }

}
hat nichts gebracht, weiterhin gab es einen Versuch mit @Type Annotation von ChatGPT, aber da hat sich einiges nicht zusammengepasst, das Attribut type wurde von Eclipse nicht erkannt und im Internet habe ich keine vergleichbare Anwendung gefunden (stattdessen gibt es ein value Attribut):

Code:
@Type(type = "org.hibernate.type.EnumType")
@Enumerated(EnumType.STRING)
@Column(columnDefinition = "ENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAY")
private List<AnimalCharacterEnum> characteristic;
 

Oneixee5

Top Contributor
Wenn du ein ENUM in deiner Entity definierst, dann musst du diese vermutlich als 'transient' deklarieren. Wie soll JPA damit umgehen? Das ENUM ist keine Spalte oder ähnliches, es ist nur Typ/Wert einer Spalte in der DB. Besser du verwendest für FoodType eine eigene Datei, wie bei AnimalCharacter.
Meiner Meinung nach ist es sauberer eine Fremdschlüsseltabelle zu verwenden. Die Anwendung lässt sich besser erweitern/ändern, einfacher mehrsprachig umsetzen und Text ist von Wert getrennt. Den Text eines Enum kann man nicht mehr ändern, ohne alle Datensätze anzupassen. Das macht alles unnötig kompliziert.
 
Zuletzt bearbeitet:

ExceptionOfExpectation

Bekanntes Mitglied
Für das FoodType gibt es gar keine Probleme. Das Problem tritt an, wenn ich die characteristic Property speichere und zwar wegen den "Set".
Die H2 Database kann mit Set-Type nicht umgehen, allerdings, wenn ich die Daten von der Datenbank abfrage, dann funktioniert alles Einwandfrei.
Ich verstehe was du meinst, aber hier wollte ich unbedingt Enums anwenden, außerdem werden keine zusätzliche Charaktereigenschaften entstehen, was FoodType angeht gilt dasselbe, den es gibt keinen weiteren relevanten Zustand.
Das Problem entsteht nur dann, wenn ich Daten hinzufügen möchte, aber nicht wenn ich die abfrage.
 

mihe7

Top Contributor
Der Typ der Spalte ist kein ENUM, sondern ein ARRAY von ENUMs. Wenn ich es richtig sehe, wird ARRAY auf ein Object gemappt und eine ENUM-Konstante wird als String dargestellt. Der Converter müsste dementsprechend etwa so aussehen:
Java:
@Converter
public class EnumArrayConverter implements AttributeConverter<Set<AnimalCharacter>, Object>{

    @Override
    public Object convertToDatabaseColumn(Set<AnimalCharacter> attribute) {
        Object[] names = attribute.stream().map(AnimalCharacter::name).toArray();
        return names;
    }

    @Override
    public Set<AnimalCharacter> convertToEntityAttribute(Object dbData) {
        Object[] chars = (Object[]) dbData;
        return Stream.of(chars).map(Object::toString).map(AnimalCharacter::valueOf).collect(Collectors.toSet());
    }    
}

Das Set müsste dann so deklariert werden:
Java:
    @Convert(converter = EnumArrayConverter.class)
    private Set<AnimalCharacter> characteristic;
 

ExceptionOfExpectation

Bekanntes Mitglied
Der Typ der Spalte ist kein ENUM, sondern ein ARRAY von ENUMs. Wenn ich es richtig sehe, wird ARRAY auf ein Object gemappt und eine ENUM-Konstante wird als String dargestellt. Der Converter müsste dementsprechend etwa so aussehen:
Java:
@Converter
public class EnumArrayConverter implements AttributeConverter<Set<AnimalCharacter>, Object>{

    @Override
    public Object convertToDatabaseColumn(Set<AnimalCharacter> attribute) {
        Object[] names = attribute.stream().map(AnimalCharacter::name).toArray();
        return names;
    }

    @Override
    public Set<AnimalCharacter> convertToEntityAttribute(Object dbData) {
        Object[] chars = (Object[]) dbData;
        return Stream.of(chars).map(Object::toString).map(AnimalCharacter::valueOf).collect(Collectors.toSet());
    }  
}

Das Set müsste dann so deklariert werden:
Java:
    @Convert(converter = EnumArrayConverter.class)
    private Set<AnimalCharacter> characteristic;
Guter Punkt, macht Sinn, nur statt Object sollte Object[] kommen, leider bekomme ich die selbe Fehlermeldung.
Ich habe meinen characteristic Type in der Datenbank Tabelle geprüft und das bekommen:
SHOW COLUMNS FROM Product_object;
FIELD TYPE NULL KEY DEFAULT
IDBIGINTNOPRINULL
CHARACTERISTICENUM('Aggressive', 'Calm', 'Curious', 'Fearful', 'Friendly', 'Independent', 'Loyal', 'None', 'Playful', 'Protective', 'Reasonable', 'Social', 'Vigorous') ARRAYYESNULL
COLORCHARACTER VARYING(255)YESNULL
COUNTINTEGERNONULL
FOOD_IDBIGINTYESNULL
FOOD_TYPEENUM('BONE', 'CANNED', 'DRINKS', 'LEFTOVER_FOOD', 'LIQUID_FOOD', 'MEAT', 'NONE', 'PRODUCTION', 'VITAMINS')YESNULL
HEIGHTNUMERIC(38, 2)YESNULL
IMAGECHARACTER VARYING(255)YESNULL
NAMECHARACTER VARYING(255)YESNULL
OBJECT_NAMECHARACTER VARYING(255)YESNULL
PRICENUMERIC(38, 2)YESNULL
PUPPY_IDBIGINTYESNULL
WEIGHTNUMERIC(38, 2)YESNULL
CATEGORY_IDBIGINTNONULL
(14 rows, 10 ms)
Das heißt für meinen Enum-array gibt es keinen geeigneten Type oder wie?
 

ExceptionOfExpectation

Bekanntes Mitglied
...

Das Set müsste dann so deklariert werden:
Java:
    @Convert(converter = EnumArrayConverter.class)
    private Set<AnimalCharacter> characteristic;
ich musste von Anfang an die @Enumerated-Annotion einfügen:
Java:
....
@Enumerated(EnumType.STRING)
@Convert(converter = EnumArrayConverter.class)
private Set<AnimalCharacter> characteristic;

denn sonst wird es nicht kompiliert.
 

ExceptionOfExpectation

Bekanntes Mitglied
Ich habe das mit genau dem oben angegebenen Converter und einer H2-DB überprüft: funktioniert einwandfrei.

Nachtrag:

Ich habe es mit Object getestet (ein Array ist auch ein Object).
Es lag an meiner @Enumated(...) Annotation. Erstes mal habe ich sie auskommentiert, daraufhin ist der Code auseinander geflogen. Als du gesagt hast, dass es bei dir klappt, habe ich es nochmal versucht und es ging auf. Anscheinend habe ich zu dem Zeitpunkt noch etwas anderes umgebaut und das muss der Grund dafür sein.
Danke für den Code Ausschnitt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
ExceptionOfExpectation Type Fehler bei der Speicherung von Entity (Hibernate/h2) Frameworks - Spring, Play, Blade, Vaadin & Co 1
W Kotlin: DB-Relationen in Spring Boot Data / Hibernate Frameworks - Spring, Play, Blade, Vaadin & Co 6
H Laden der Hibernate Cfg in .jar Frameworks - Spring, Play, Blade, Vaadin & Co 5
ExceptionOfExpectation Persistierung in Hibernate(SpringBoot) Frameworks - Spring, Play, Blade, Vaadin & Co 10
padde479 org.hibernate.query.sqm.UnknownEntityException Frameworks - Spring, Play, Blade, Vaadin & Co 12
OnDemand Jasypt Hibernate 6 alternative gesucht Frameworks - Spring, Play, Blade, Vaadin & Co 3
Avalon @Query Select Abfrage liefert falsche Werte (Spring Boot, JPA, Hibernate) Frameworks - Spring, Play, Blade, Vaadin & Co 3
D org.hibernate.LazyInitializationException Frameworks - Spring, Play, Blade, Vaadin & Co 2
krgewb Hibernate - deleteByXXX Frameworks - Spring, Play, Blade, Vaadin & Co 3
Z Postgres, Hibernate Seqencenummer wird wiederholt und verursacht PK-Fehler Frameworks - Spring, Play, Blade, Vaadin & Co 3
Z JPA, Hibernate, Postgres und Sequence-Nummern Frameworks - Spring, Play, Blade, Vaadin & Co 3
Z Hibernate & Postgres in Spring Boot (Syntaxprobleme) Frameworks - Spring, Play, Blade, Vaadin & Co 2
Z Spring Boot mit JPA;, Hibernate, Rest & Lombok Frameworks - Spring, Play, Blade, Vaadin & Co 8
OnDemand Jasypt Spring Boot HIbernate wie komme ich an den Key? Frameworks - Spring, Play, Blade, Vaadin & Co 4
OnDemand Hibernate Lazy Collection löschen Frameworks - Spring, Play, Blade, Vaadin & Co 7
H Hibernate Sql Abfrage loggen Spring mit log4j.properties Frameworks - Spring, Play, Blade, Vaadin & Co 2
OnDemand DTO <> Entity Hibernate Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 28
S Spring JPA / Hibernate: save Methode arbeitet nicht Frameworks - Spring, Play, Blade, Vaadin & Co 2
R Spring Data: Hibernate liest nicht alle Ebenen Frameworks - Spring, Play, Blade, Vaadin & Co 5
S Spring Data Hibernate mehrfache Suchkriterien Frameworks - Spring, Play, Blade, Vaadin & Co 5
H Spring Boot, Hibernate und OAuth2 wie komme ich an den User? Frameworks - Spring, Play, Blade, Vaadin & Co 13
D Spring Hibernate Struts2 ? Frameworks - Spring, Play, Blade, Vaadin & Co 1
F JPA org.hibernate.LazyInitializationException / Spring @Transactional Frameworks - Spring, Play, Blade, Vaadin & Co 5
P Spring, Hibernate und JPA in einem Projekt Frameworks - Spring, Play, Blade, Vaadin & Co 4
I Nachladen mit Hibernate und Spring Frameworks - Spring, Play, Blade, Vaadin & Co 2
N MAVEN + Spring + JPA + Hibernate + JUnit4 Frameworks - Spring, Play, Blade, Vaadin & Co 5
E Tomcat mit Hibernate und Spring - Problem mit Connection Pool Frameworks - Spring, Play, Blade, Vaadin & Co 5
P Context initialization failed - mit Spring, JPA, Hibernate Frameworks - Spring, Play, Blade, Vaadin & Co 1
B Buchempfehlung für Groovy, Spring, Hibernate, SOAP, J2EE gesucht Frameworks - Spring, Play, Blade, Vaadin & Co 1
D Hibernate - Spring Roo Frameworks - Spring, Play, Blade, Vaadin & Co 0
Dit_ Springsource Toolsuit | Hibernate intergration Frameworks - Spring, Play, Blade, Vaadin & Co 1
J Test mit Hibernate und Spring Frameworks - Spring, Play, Blade, Vaadin & Co 5
D [InvalidDataAccessApiUsageException] Spring Data JPA / Hibernate Frameworks - Spring, Play, Blade, Vaadin & Co 1
B SpringMVC-EntityManagerFactory-Hibernate-Problem Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Problem mit Hibernate und Spring Frameworks - Spring, Play, Blade, Vaadin & Co 0
R Projektübergreifende Entities mit Tomcat (Spring/JPA/Hibernate) Frameworks - Spring, Play, Blade, Vaadin & Co 2
N Wie manage ich unter Spring mehrere Datenbankverbindung mit Hibernate Frameworks - Spring, Play, Blade, Vaadin & Co 6
Y Sessionmanagement (ThreadLocal) in Hibernate via Spring möglich? Frameworks - Spring, Play, Blade, Vaadin & Co 2
C Aufgabe in OSGI/Hibernate/Spring-DM Frameworks - Spring, Play, Blade, Vaadin & Co 4
dunhillone Problem mit Spring & Hibernate Sessions Frameworks - Spring, Play, Blade, Vaadin & Co 2
dunhillone Problem mit Spring & Hibernate Sessions Frameworks - Spring, Play, Blade, Vaadin & Co 2
B Spring / Jpa / Hibernate -> java.lang.IllegalArgumentException: Unknown entity Frameworks - Spring, Play, Blade, Vaadin & Co 1
S Hibernate und JDBC über Spring Frameworks - Spring, Play, Blade, Vaadin & Co 3
8u3631984 "detached entity passed to persist" Fehler beim Speichern eine Entity Frameworks - Spring, Play, Blade, Vaadin & Co 3
8u3631984 Ist es möglich in Spring Entity generische Listen verwenden Frameworks - Spring, Play, Blade, Vaadin & Co 3
M Spring Boot additional Datasource for a single entity Frameworks - Spring, Play, Blade, Vaadin & Co 0
M Spring Entity testen Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Spring Entity testen Frameworks - Spring, Play, Blade, Vaadin & Co 5
Z JPA Extra-Entity für Many-To-Many gewissermaßen zu Fuß Frameworks - Spring, Play, Blade, Vaadin & Co 5
8u3631984 JPA - Entity dopplet inder Datenbank verhindern - UniqueConstraint scheitern aufgrund Vererbung ? Frameworks - Spring, Play, Blade, Vaadin & Co 5
8u3631984 Save Entity With List of entities Frameworks - Spring, Play, Blade, Vaadin & Co 3
L Spring Data: Detached Entity passed to persist Fehler Frameworks - Spring, Play, Blade, Vaadin & Co 6
L Spring Data: Multiple representations of the same entity Frameworks - Spring, Play, Blade, Vaadin & Co 14
L Spring JPA Entity Definierung Frameworks - Spring, Play, Blade, Vaadin & Co 0

Ähnliche Java Themen


Oben