Reputation: 1161
I have two entity classes defined. One called EncryptedFile
and the other called Chat
.
I have stripped out the code down to the root problem.
Chat
:
package database.objects
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "chats")
class Chat extends DatabaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "chat_id")
var id: Int = _
@OneToMany(mappedBy = "chat", cascade = Array(CascadeType.ALL), fetch = FetchType.LAZY)
var files: java.util.List[EncryptedFile] = new java.util.ArrayList[EncryptedFile]()
}
EncryptedFile
:
package database.objects
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "files")
class EncryptedFile extends DatabaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "file_id")
var id: Int = _
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "chat_id", referencedColumnName = "chat_id")
var chat: Chat = _
}
And finally, my Hibernate
config:
val jasyptConfig = new JasyptConfig()
.addAnnotatedClass(classOf[Server])
.addAnnotatedClass(classOf[Chat])
.addAnnotatedClass(classOf[User])
.addAnnotatedClass(classOf[EncryptedFile])
.setProperty(JAKARTA_JDBC_URL, "jdbc:mysql://localhost:3306/hydra_data")
.setProperty(JAKARTA_JDBC_USER, sqlUser)
.setProperty(JAKARTA_JDBC_PASSWORD, sqlPass)
// use Agroal connection pool
.setProperty("hibernate.agroal.maxSize", "20")
.setProperty("hibernate.hbm2ddl.auto", "update")
.setProperty("hibernate.cache.use_second_level_cache", true)
.setProperty("hibernate.cache.use_query_cache", true)
.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.jcache.JCacheRegionFactory")
.setProperty("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider")
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect")
Not sure if relevant, but I'm using a custom build of Jasypt that I have ported for Hibernate 6. The JasyptConfig
is this:
public class JasyptConfig extends Configuration {
public JasyptConfig() {
// register custom converters
addAnnotatedClass(EncryptedBigDecimalAsString.class);
addAnnotatedClass(EncryptedBigDecimal.class);
addAnnotatedClass(EncryptedBigIntegerAsString.class);
addAnnotatedClass(EncryptedBigInteger.class);
addAnnotatedClass(EncryptedBinary.class);
addAnnotatedClass(EncryptedBooleanAsString.class);
addAnnotatedClass(EncryptedByteAsString.class);
addAnnotatedClass(EncryptedCalendarAsString.class);
addAnnotatedClass(EncryptedDateAsString.class);
addAnnotatedClass(EncryptedDoubleAsString.class);
addAnnotatedClass(EncryptedDoubleAsString.class);
addAnnotatedClass(EncryptedFloatAsString.class);
addAnnotatedClass(EncryptedIntegerAsString.class);
addAnnotatedClass(EncryptedLongAsString.class);
addAnnotatedClass(EncryptedShortAsString.class);
addAnnotatedClass(EncryptedString.class);
}
...
}
When I come to run my application, I get the following error:
Exception in thread "main" org.hibernate.AnnotationException: Collection 'database.objects.Chat.files' is declared with a raw type and has an explicit 'targetEntity'
at org.hibernate.boot.model.internal.CollectionBinder.getElementType(CollectionBinder.java:1591)
at org.hibernate.boot.model.internal.CollectionBinder.noAssociationTable(CollectionBinder.java:1650)
at org.hibernate.boot.model.internal.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:1613)
at org.hibernate.boot.model.internal.CollectionBinder$1.secondPass(CollectionBinder.java:1604)
at org.hibernate.boot.model.internal.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1842)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1800)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:334)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:129)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:449)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:101)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:949)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:999)
at database.Database.init(Database.scala:87)
at database.DatabaseUtil$.getInstance(Database.scala:34)
at core.Main$.main(Main.scala:38)
at core.Main.main(Main.scala)
I can solve the error by explicitly declaring targetEntity
as described here: Hibernate: Collection is declared with a raw type and has an explicit 'targetEntity'
What I would like to know is why this happens? The error specifically suggests that the problem is the rawType
and the targetEntity
being set, yet it only goes away when both are set.
Is there a reason, or is it just poor wording in the exception?
Note:
I have reworded this question to understand better why this error is happening, as the other solution does not explain this.
I'm not the kind of person to just take a solution at face value and go "yep, it works" and move on. I need to understand why it is that it works, especially when the error is suggesting it shouldn't work.
Please re-open the question.
Upvotes: 1
Views: 25