Hi,
I have problems with mixing JPA annotations and orm.xml mapping file together.
Because of the usage of a internal framework the class InternalModelObject is used with a mapping file instead of annotations.
I also use field access consciously because of some internal guidelines.
If I use the class InternalModelObject with annotations everything works fine. But do I substitute the annotations I get the following exception
Code:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.MappingException: Could not determine type for: java.util.Collection, for columns: [org.hibernate.mapping.Column(countries)]
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:737)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at ch.admin.insieme.persistence.driver.JPATestDriver.main(JPATestDriver.java:21)
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Collection, for columns: [org.hibernate.mapping.Column(countries)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:266)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:253)
at org.hibernate.mapping.Property.isValid(Property.java:185)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:440)
at org.hibernate.mapping.RootClass.validate(RootClass.java:192)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1102)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1287)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:730)
... 4 more
For me, the mapping file looks exactly as the annotated class. Field access is also defined.
Where is the problem???
I use the following hierarchie. Gen classes are generated with MDD.
Code:
package ch.admin.insieme.persistence.model;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
@MappedSuperclass
public abstract class AddressGen extends InternalModelObject implements Address {
private String city;
private String zipCode;
private String street;
@OneToMany(targetEntity = CountryImpl.class)
@JoinColumn(name = "ADDRESS_ID")
private Collection<Country> countries = new HashSet<Country>();
public AddressGen() {
// TODO Auto-generated constructor stub
}
public AddressGen(String city, String zipCode, String street,
Collection<Country> countries) {
setContent(city, zipCode, street, countries);
}
public void setContent(String city, String zipCode, String street,
Collection<Country> countries) {
checkConstraint(city, zipCode, street, countries);
this.city = city;
this.zipCode = zipCode;
this.street = street;
this.countries = countries;
}
public String getCity() {
return city;
}
public String getZipCode() {
return zipCode;
}
public String getStreet() {
return street;
}
public Collection<Country> getCountries() {
return Collections.unmodifiableCollection(countries);
}
public void setCity(String city) {
setContent(city, getZipCode(), getStreet(), getCountries());
}
public void setStreet(String street) {
setContent(getCity(), getZipCode(), street, getCountries());
}
public void setZipCode(String zipCode) {
setContent(getCity(), zipCode, getStreet(), getCountries());
}
public abstract void checkConstraint(String city, String zipCode, String street,
Collection<Country> countries);
}
Code:
import java.util.Collection;
import javax.persistence.Entity;
@Entity
public class AddressImpl extends AddressGen {
public AddressImpl() {
// TODO Auto-generated constructor stub
}
public AddressImpl(String stadt, String plz, String strasse,
String postfach, Collection<Country> countries) {
super(stadt, plz, strasse, countries);
}
@Override
public void checkConstraint(String city, String zipCode, String street,
Collection<Country> countries) {
// TODO Auto-generated method stub
}
}
Code:
import javax.persistence.MappedSuperclass;
@MappedSuperclass
public abstract class CountryGen extends InternalModelObject implements Country{
private String countryName;
private String countryCode;
public CountryGen() {
// TODO Auto-generated method stub
}
public CountryGen(String countryName, String countryCode) {
setContent(countryName, countryCode);
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
setContent(getCountryName(), countryCode);
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
setContent(countryName, getCountryCode());
}
public void checkConstraint(String countryName, String countryCode) {
// Check criteria
}
public void setContent(String countryName, String countryCode) {
checkConstraint(countryName, countryCode);
this.countryName = countryName;
this.countryCode = countryCode;
}
public abstract void checkConstraint();
}
Code:
import javax.persistence.Entity;
@Entity
public class CountryImpl extends CountryGen{
public CountryImpl() {
// TODO Auto-generated method stub
}
public CountryImpl(String countryName, String countryCode) {
super(countryName, countryCode);
}
@Override
public void checkConstraint() {
// TODO Auto-generated method stub
}
}
Code:
//@MappedSuperclass
public class InternalModelObject {
// @Id
// @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
}
The orm.xml mapping file
Code:
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<mapped-superclass
class="ch.admin.insieme.persistence.model.InternalModelObject"
access="FIELD" metadata-complete="true">
<attributes>
<id name="id">
<column name="ID" />
<generated-value strategy="AUTO" />
</id>
</attributes>
</mapped-superclass>
</entity-mappings>
and the appropriate persistence.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="JPATestPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/jpatest;create=true"/>
<property name="hibernate.connection.username" value="APP"/>
<property name="hibernate.connection.password" value="APP"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
The little driver looks like this
Code:
public class JPATestDriver {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("JPATestPU");
EntityManager em = emf.createEntityManager();
EntityTransaction t = em.getTransaction();
t.begin();
Collection<Country> countries = new HashSet<Country>();
Country country = new CountryImpl("CH", "0041");
countries.add(country);
em.persist(country);
Address adress = new AddressImpl("Bern", "3012", "Holzikofenweg",
"4711", countries);
em.persist(adress);
t.commit();
em.close();
}
}
I use JPA with Hibernate 3.2 and MyEclipse 7.1.1