Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a generic QualifiedJsonType that saves serializes the Java object types #361

Open
vladmihalcea opened this issue Oct 28, 2021 · 0 comments

Comments

@vladmihalcea
Copy link
Owner

The new QualifiedJsonType will allow you to save the associated Java type of each JSON Array or Object contained in the JSON column value.

This is going to be useful when the entity property is mapped as an interface or abstract class reference or collection of references.

So, assuming you have the following class hierarchy:

public static abstract class Topic implements Serializable {

    private String title;

    public Topic() {
    }

    public Topic(String title) {
        this.title = title;
    }
}

public static class Post extends Topic {

    private String content;

    public Post() {
    }

    public Post(String title) {
        super(title);
    }
}

public static class Announcement extends Topic {

    private Date validUntil;

    public Announcement() {
    }

    public Announcement(String title) {
        super(title);
    }
}

The QualifiedJsonType will allow you to map that hierarchy either as a List:

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(name = "qualified-json", typeClass = QualifiedJsonType.class)
public static class Book {

    @Id
    @GeneratedValue
    private Long id;

    @NaturalId
    @Column(length = 15)
    private String isbn;

    @Type(type = "qualified-json")
    @Column(columnDefinition = "jsonb")
    private List<Topic> topics = new ArrayList<>();
}

And, when persisting the Post, the following INSERT is generated:

Params:[(
    978-9730228236, 
    [
        "java.util.ArrayList", [
            [
                "com.vladmihalcea.hibernate.type.json.polymorphic.PostgreSQLQualifiedJsonListTest$Post",
                {
                    "title":"High-Performance Java Persistence",
                    "content":
                    "It rocks!"
                }
            ], 
            [
                "com.vladmihalcea.hibernate.type.json.polymorphic.PostgreSQLQualifiedJsonListTest$Announcement",
                {
                    "title":"Black Friday - 50% discount",
                    "validUntil":["java.util.Date",1636269852550]
                }
            ]
        ]
    ], 
   1
)]

Or, as a Map:

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(name = "qualified-json", typeClass = QualifiedJsonType.class)
public static class Book {

    @Id
    @GeneratedValue
    private Long id;

    @NaturalId
    @Column(length = 15)
    private String isbn;

    @Type(type = "qualified-json")
    @Column(columnDefinition = "jsonb")
    private Map<String, Topic> topics = new HashMap<>();
    
}

In which case, the Post is saved like this:

Query:["insert into book (isbn, topics, id) values (?, ?, ?)"], 
Params:[(
    978-9730228236, 
    [
        "java.util.HashMap",
        {
            "Announcement":[
                "com.vladmihalcea.hibernate.type.json.polymorphic.PostgreSQLQualifiedJsonMapTest$Announcement",
                {
                    "title":"Black Friday - 50% discount",
                    "validUntil":["java.util.Date",1636270574050]
                }
            ],
            "Post":[
                "com.vladmihalcea.hibernate.type.json.polymorphic.PostgreSQLQualifiedJsonMapTest$Post",
                {
                    "title":"High-Performance Java Persistence",
                    "content":"It rocks!"
                }
            ]
        }
    ], 
    1
)]

The QualifiedJsonType will be able to persist any class hierarchy, not just the ones annotated with the much more limited Jackson JsonTypeInfo annotation.

Repository owner locked and limited conversation to collaborators Oct 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant