Reputation: 31895
I have a field in Postgres in array type:
categories | text[] | | |
How can I declare the field in the entity class?
I have tried below in Product.kt
file but it throws error [ERROR]:ERROR: relation "product_categories" does not exist
@ElementCollection
@Column(name = "categories")
var categories: List<String>? = emptyList()
My purpose is to save the string array as one field of the entity, I am not trying to do anything related "One to Many".
If you know any Java version solution and it works, I will accept the answer as well. Thanks
Upvotes: 5
Views: 3827
Reputation: 1
Apart from the one mentioned by Haifeng, for Kotlin, there is another option to use ListArrayType
instead of StringArrayType
so you do not need to care about converting list to array.
I met another issue retrieving the data, I had java.lang.ArrayStoreException: arraycopy: type mismatch: can not copy [Ljava.lang.String;[] into java.lang.String[]\n
. Just for those who may also encounter this, my issue was the data storing in DB is not array but array of array.
Upvotes: 0
Reputation: 31895
Adam's answer works for projects written in Java. As my project is written in Kotlin, I share my version below and hope it helps and people can use it right away other than spending time to convert:
Useful resource: How to map Java and SQL arrays with JPA and Hibernate
Postgres:
alter table product add column categories text[];
Gradle:
implementation("com.vladmihalcea:hibernate-types-52:2.10.0")
Product.kt
import com.vladmihalcea.hibernate.type.array.StringArrayType
import org.hibernate.annotations.*
import javax.persistence.*
import javax.persistence.Entity
@TypeDefs(
TypeDef(name = "string-array", typeClass = StringArrayType::class)
)
@Entity
class Product(
var name: String,
@Type(type = "string-array")
@Column(name = "categories", columnDefinition = "text[]")
var categories: Array<String>? = arrayOf(),
)
There're 2 differences between Java and Kotlin:
Upvotes: 4
Reputation: 30528
This won't work with @ElementCollection
as it will always try to use another table. What you need is a custom type instead. For this you'll need this dependency:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
then you can define your own types:
import com.vladmihalcea.hibernate.type.array.StringArrayType
@TypeDefs({
@TypeDef(
name = "string-array",
typeClass = StringArrayType.class
)
})
@Entity
class YourEntity {
@Type( type = "string-array" )
@Column(
name = "categories",
columnDefinition = "character varying[]"
)
var categories: Array<String>;
}
I haven't tried this with a List
though, as this maps to an Array
. More info in this answer.
Upvotes: 3