Note that there are some explanatory texts on larger screens.

plurals
  1. PO@Embeddable Issue with Spring and Hibernate3
    text
    copied!<p>I am having an issue with mapping my entities to achieve a many-to-many join table using @Embeddable class as the join class representative. Basically here is what I am trying to achieve:</p> <p><img src="https://i.stack.imgur.com/kh7jG.png" alt="enter image description here"></p> <p>I followed the tutorials given in the Java Hibernate Persistence book and I am still receiving errors from these methods:</p> <blockquote> <p>org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: nz.co.doltech.ims.project.server.entities.CategoryEntity.incidentCategoryJoins[nz.co.doltech.ims.project.server.entities.IncidentCategoryJoin] at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1185) at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:710) at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:645) at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:65) at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1716) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1423) at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375) at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:720) at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)</p> </blockquote> <p>I am setting up hibernate using spring:</p> <blockquote> <p>org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean</p> </blockquote> <p><strong>Spring Appcontext.xml:</strong></p> <pre class="lang-xml prettyprint-override"><code>&lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"&gt; &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt; &lt;context:annotation-config /&gt; &lt;context:component-scan base-package="nz.co.doltech.ims" /&gt; &lt;aop:aspectj-autoproxy /&gt; &lt;!-- Configurer that replaces ${...} placeholders with values from a properties file --&gt; &lt;bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt; &lt;property name="locations"&gt; &lt;list&gt; &lt;value&gt;classpath:nz/co/doltech/ims/paths.properties&lt;/value&gt; &lt;value&gt;classpath:nz/co/doltech/ims/project/project.properties&lt;/value&gt; &lt;value&gt;classpath:nz/co/doltech/ims/framework/framework.properties&lt;/value&gt; &lt;/list&gt; &lt;/property&gt; &lt;property name="ignoreResourceNotFound" value="no"/&gt; &lt;/bean&gt; &lt;!-- Hibernate Data Source --&gt; &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt; &lt;property name="driverClassName" value="${project.database.driver}" /&gt; &lt;property name="url" value="${project.database.url}" /&gt; &lt;property name="username" value="${project.database.user}" /&gt; &lt;property name="password" value="${project.database.password}" /&gt; &lt;/bean&gt; &lt;!-- Hibernate SessionFactory --&gt; &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt;&lt;!-- depends-on="flyway" --&gt; &lt;!-- property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /--&gt; &lt;property name="dataSource"&gt; &lt;ref bean="dataSource" /&gt; &lt;/property&gt; &lt;property name="packagesToScan"&gt; &lt;list&gt; &lt;value&gt;${paths.project}.server.entities&lt;/value&gt; &lt;/list&gt; &lt;/property&gt; &lt;property name="hibernateProperties"&gt; &lt;props&gt; &lt;prop key="hibernate.dialect"&gt;${project.hibernate.dialect}&lt;/prop&gt; &lt;prop key="hibernate.show_sql"&gt;${project.hibernate.show_sql}&lt;/prop&gt; &lt;prop key="hibernate.hbm2ddl.auto"&gt;${project.hibernate.hbm2ddl}&lt;/prop&gt; &lt;prop key="javax.persistence.validation.mode"&gt;none&lt;/prop&gt; &lt;/props&gt; &lt;/property&gt; &lt;/bean&gt; &lt;!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --&gt; &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt; &lt;property name="sessionFactory" ref="sessionFactory" /&gt; &lt;/bean&gt; &lt;bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"&gt; &lt;property name="sessionFactory" ref="sessionFactory" /&gt; &lt;/bean&gt; &lt;/beans&gt; </code></pre> <p>Here are my annotated entity classes</p> <p><strong>CategoryEntity.java:</strong></p> <pre class="lang-java prettyprint-override"><code>@javax.persistence.Entity @Table(name = "categories") public class CategoryEntity implements Entity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(unique = true, nullable = false) private int id = Entity.UNSAVED_ID; @Basic(optional = false) @Column(nullable = false, length = 128) private String name; @Basic(optional = false) @Column(nullable = false, length = 512) private String description; @OneToMany(mappedBy = "category") private Set&lt;IncidentCategoryJoin&gt; incidentCategoryJoins; @JoinTable( name = "category_categorytype", joinColumns = @JoinColumn(name = "category_id") ) private Set&lt;CategoryTypeJoin&gt; categoryTypeJoins; // id column @Override public int getId() { return this.id; } public void setId(int id) { this.id = id; } // name column public String getName() { return this.name; } public void setName(String name) { this.name = name; } // description column public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } // incident join columns public Set&lt;IncidentCategoryJoin&gt; getIncidentCategoryJoins() { return incidentCategoryJoins; } public void setIncidentCategoryJoins(Set&lt;IncidentCategoryJoin&gt; incidentCategoryJoins) { this.incidentCategoryJoins = incidentCategoryJoins; } // category type join columns public Set&lt;CategoryTypeJoin&gt; getCategoryTypeJoins() { return categoryTypeJoins; } public void setCategoryTypeJoins(Set&lt;CategoryTypeJoin&gt; categoryTypeJoins) { this.categoryTypeJoins = categoryTypeJoins; } } </code></pre> <p><strong>IncidentsEntity.java:</strong></p> <pre class="lang-java prettyprint-override"><code>@javax.persistence.Entity(name = "incidents") public class IncidentEntity implements Entity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(unique = true, nullable = false) private int id = Entity.UNSAVED_ID; @Basic private String owner; @Column(length = 256) private String description; @Column(name="creation_date") private String creationDate; @Column(length = 128) private String title; @Column(length = 20) private String date; @Column(name="location_details", length = 512) private String locationDetails; @Column(name="authorities_involved", length = 512) private String authInvolved; private int status; private int state; @Column(name="sub_state") private int subState; @Column(name="reported_by") private int reportedBy; @JoinTable( name = "incident_category", joinColumns = @JoinColumn(name = "incident_id") ) @Embedded private Set&lt;IncidentCategoryJoin&gt; incidentCategoryJoins; // id column @Override public int getId() { return this.id; } public void setId(int id) { this.id = id; } // description column public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } // owner column public String getOwner() { return this.owner; } public void setOwner(String owner) { this.owner = owner; } // creation date column public String getCreationDate() { return this.creationDate; } public void setCreationDate(String creationDate) { this.creationDate = creationDate; } // title column public String getTitle() { return this.title; } public void setTitle(String title) { this.title = title; } // date column public String getDate() { return this.date; } public void setDate(String date) { this.date = date; } // location details column public String getLocationDetails() { return locationDetails; } public void setLocationDetails(String locationDetails) { this.locationDetails = locationDetails; } // authorities involved column public String getAuthInvolved() { return authInvolved; } public void setAuthInvolved(String authInvolved) { this.authInvolved = authInvolved; } // status column public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } // state column public int getState() { return state; } public void setState(int state) { this.state = state; } // sub state column public int getSubState() { return subState; } public void setSubState(int subState) { this.subState = subState; } // reported by column public int getReportedBy() { return reportedBy; } public void setReportedBy(int reportedBy) { this.reportedBy = reportedBy; } // categories join columns public Set&lt;IncidentCategoryJoin&gt; getIncidentCategoryJoins() { return incidentCategoryJoins; } public void getIncidentCategoryJoins(Set&lt;IncidentCategoryJoin&gt; incidentCategoryJoins) { this.incidentCategoryJoins = incidentCategoryJoins; } } </code></pre> <p><strong>CategoryTypeEntity.java:</strong></p> <pre class="lang-java prettyprint-override"><code>@javax.persistence.Entity @Table(name = "categorytypes") public class CategoryTypeEntity implements Entity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id = Entity.UNSAVED_ID; @Basic(optional = false) @Column(nullable = false, length = 128) private String name; @Basic(optional = false) @Column(nullable = false, length = 512) private String description; @OneToMany(mappedBy = "categoryType") private Set&lt;CategoryTypeJoin&gt; categoryTypeJoins; @OneToMany(mappedBy = "categoryType") private Set&lt;IncidentCategoryJoin&gt; incidentCategoryJoins; @Override public int getId() { return this.id; } public void setId(int id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } public Set&lt;CategoryTypeJoin&gt; getCategoryTypeJoins() { return categoryTypeJoins; } public void setCategoryTypeJoins(Set&lt;CategoryTypeJoin&gt; categoryTypeJoins) { this.categoryTypeJoins = categoryTypeJoins; } } </code></pre> <p>So I am joining these tables with the @Embeddable annotation so that hibernate can map it into the entities. But as you can see in the error message, it is not mapping at all.</p> <p><strong>IncidentCategoryJoin.java:</strong></p> <pre class="lang-java prettyprint-override"><code>@Embeddable public class IncidentCategoryJoin implements Serializable { @Parent // Optional back-pointer private IncidentEntity incident; @ManyToOne @JoinColumn(name="category_id", insertable = false, updatable = false) private CategoryEntity category; @ManyToOne @JoinColumn(name="categorytype_id", insertable = false, updatable = false) private CategoryTypeEntity categoryType; public IncidentCategoryJoin() {} public IncidentCategoryJoin( IncidentEntity incident, CategoryEntity category, CategoryTypeEntity categoryType) { // Set fields this.incident = incident; this.category = category; this.categoryType = categoryType; // Guarantee referential integrity incident.getIncidentCategoryJoins().add(this); category.getIncidentCategoryJoins().add(this); } public IncidentEntity getIncident() { return incident; } public void setIncident(IncidentEntity incident) { this.incident = incident; } public CategoryEntity getCategory() { return category; } public void setCategory(CategoryEntity category) { this.category = category; } public CategoryTypeEntity getCategoryType() { return categoryType; } public void setCategoryType(CategoryTypeEntity categoryType) { this.categoryType = categoryType; } public boolean equals(Object o) { if (o != null &amp;&amp; o instanceof IncidentCategoryJoin) { IncidentCategoryJoin that = (IncidentCategoryJoin)o; return this.category.equals(that.getCategory()) &amp;&amp; this.incident.equals(that.getIncident()) &amp;&amp; this.categoryType.equals(that.getCategoryType()); } else { return false; } } public int hashCode() { return category.getId() + incident.getId() + categoryType.getId(); } } </code></pre> <p><strong>CategoryTypeJoin.java:</strong></p> <pre class="lang-java prettyprint-override"><code>@Embeddable public class CategoryTypeJoin implements Serializable { @Parent // Optional back-pointer private CategoryEntity category; @ManyToOne @JoinColumn(name="categorytype_id", insertable = false, updatable = false) private CategoryTypeEntity categoryType; public CategoryTypeJoin() {} public CategoryTypeJoin( CategoryEntity category, CategoryTypeEntity categoryType) { // Set fields this.category = category; this.categoryType = categoryType; // Guarantee referential integrity category.getCategoryTypeJoins().add(this); categoryType.getCategoryTypeJoins().add(this); } public CategoryEntity getCategory() { return category; } public void setCategory(CategoryEntity category) { this.category = category; } public CategoryTypeEntity getCategoryType() { return categoryType; } public void setCategoryType(CategoryTypeEntity categoryType) { this.categoryType = categoryType; } public boolean equals(Object o) { if (o != null &amp;&amp; o instanceof IncidentCategoryJoin) { IncidentCategoryJoin that = (IncidentCategoryJoin)o; return this.category.equals(that.getCategory()) &amp;&amp; this.categoryType.equals(that.getCategoryType()); } else { return false; } } public int hashCode() { return category.getId() + categoryType.getId(); } } </code></pre> <p>Does anyone have any ideas as to why this is not working for me?? Bare in mind that I have followed this method from the official Java Hibernate Persistence book, so in theory it should be working fine for me. I have been considering the possibility of a bug in Spring or hibernate. Anyway I would appreciate any help that I can get here.</p> <p>Cheers, Ben Dol</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload