I've seen this question asked a lot and I know why it happens, I'm just having issues trying to solve it in my specific case.
I'm converting the project I'm working on from using XML files to map classes to database tables for Hibernate, to using Hibernate annotations. Everything is going fine as long as I'm using basic java types (primitives or class versions of primitives, e.g. int or Integer). But when it comes to my class having a member that is another class of mine, things go south.
One type of issue is when I have OnetoMany relationship.
In the XML file for foo it says this:
<set inverse="true" name="barList">
<key>
<column name="foo_id"/>
</key>
<one-to-many class="com.me.model.dao.Bar" />
</set>
In converting this to an annotation, I end up with this:
#OneToMany
#JoinTable(name = "bar", inverseJoinColumns = #JoinColumn(name = "foo_id"))
public Set<Bar> getBarList() {
return barList;
}
I've tried other variations of this (including have a JoinColumn), and I know as it stands it may be incomplete, but like I said, I'm having trouble finding a proper solution to get rid of the lazy initial exception when I'm working with the objects in the view of my MVC. FetchType.EAGER is said to be a workaround and not a solution, but curiously, solutions are not offered. Maybe more information is needed.
My MVC is Wicket 1.4.17.
My app server is Widlfly (i.e. no web.xml)
Java version is 8.
Hibernate, through Maven POM
artifact : hibernate
version : 3.5.0.ga
artifact : ejb3-persistence
version : 1.0.1.GA
Edit: It might be helpful to add that while barList appears in the foo class, there is no reference of any kind to bar in foo in the database. The foo table does have a bar_id.
Actually, annotation help to make the mapping more simple and easily. Both xml or annotation are also the same ideas(to make Hibernate to understand our objects' relationship). In this case, the mapping just simple like:
#OneToMany(mappedBy="foo")
private Set<Bar> barList;
For the whole detail, this sample looks like the same yours: https://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/
Hope this help.
I think it depends on your transaction management configuration because when you use FetchType.LAZY your lazy list not loaded until you call it by its getter method.
So that if you invoke getter method after commit transaction, this exception throws.
Please check your transaction configuration or send that part of code here.
Related
I'm using the Java Persistence API to describe tables from my database that i will manipulate in my code.
However, the schema used is not be the same depending on where my project will be installed. So, when I use the annotations, I would like that the SCHEMA field was a variable, but I can't make it:
#Entity
#Table(name = "TABLE_NAME", schema = schemaVariable, catalog = "")
How can I achieve that?
Is it possible with the persistence.xml file?
No, this is not possible. You can only use compile-time constants (which are all primitives and String) in annotations.
You can use final variables:
public class DatabaseMetadata {
public static final SCHEMA = "MySchema";
}
and then use it in annotation:
#Table(name = "TABLE_NAME", schema = DatabaseMetadata.SCHEMA, catalog = "")
but I think it's not what you wanted.
PS. On the other hand, there can be find examples of using i.e. Spring EL in annotations (see #Value annotation), but this requires custom annotation processor. AFAIK none of JPA providers gives you such ablility.
Putting schema information (like table, column, schema names) in java classes is a bad idea any time IMHO (forcing recompile if you want to deploy elsewhere). You could put that info in orm.xml and just deploy a different orm.xml dependent on your deployment requirement.
As for persistence.xml you would be dependent on your JPA provider having a persistence property that defined the default schema/catalog. I know DataNucleus JPA (what I use) has this, but no idea for Hibernate
If you know that you would be using different schemas, I'd suggest to use 2 mapping files and define
<entity-mappings>
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>HR</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
...
</entity-mappings>
In this way you will be able to easily change schemas, without any changes in the application code.
I have a class A :
#Entity
public class A {
...
#ManyToMany
private Set<Ref> refs = new HashSet<Ref>();
...
}
And a class Ref :
#Entity
public class Ref {
// no link to A
}
I want to delete A and A_Ref but not Ref, but i get a org.hibernate.exception.ConstraintViolationException
Is there a simple way to do it or should i explicitely create a A_Ref class ?
Thanks
Edit :
I was attempting to delete my list of A directly in hql. I did it in object (broke the relations) and it worked (cascade + orphan deletion).
I am not sure, if I got you right, but from what I understood my first guess is, that you havent used all necessary annotations to make sure, that hibernate will automatically remove necessary references in Ref by itself.
Within a manyToMany relation, you can use joinTables and cascadetypes to make sure, that hibernate knows where to delete all necessary relations by itself without creating an own domainObject for it.
There are plenty of nice guides how to manage it. On first view the guide from mkyong looks pretty good. Note: He annotated getters instead of variable declarations! (which is just a question of taste).
I am receiving the following Hibernate Exception:
org.hibernate.AnnotationException: #OneToOne or #ManyToOne on cz.rohan.dusps.model.Switchport.konfiguracniTemplateAccess references an unknown entity: cz.rohan.dusps.model.KonfiguracniTemplate
org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:103)
org.hibernate.cfg.AnnotationConfiguration.processEndOfQueue(AnnotationConfiguration.java:541)
org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:523)
org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:380)
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1377)
org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
cz.rohan.dusps.helper.SessionFactoryHelper.initFactory(SessionFactoryHelper.java:122)
cz.rohan.dusps.helper.SessionFactoryHelper.getSessionFactory(SessionFactoryHelper.java:134)
cz.rohan.dusps.filter.HistorieZmenFilter.doFilter(HistorieZmenFilter.java:102)
cz.rohan.dusps.filter.CharsetFilter.doFilter(CharsetFilter.java:41)
after ~20 hours spent on the problem with various people, having read every possible blog or forum, I am really getting desperate here.
This is a mid-sized project. I should mention the database is Postgres 9.1 and we generate the DB using a modelling tool. Hibernate connects to the database but does not generate it.
I have created a new entity in the database, it's called "KonfiguracniTemplate" (configuration template). I have created the model, controller, form, validators, .jsp's, all basically copied 1:1 from an existing entity of a similar nature. I can now work with KonfiguracniTemplate, CRUD is fully working.
The problem comes when I reference this KonfiguracniTemplate from the entity called Switchport. In the DB there is a relation between the two:
Switchport 1:1 ... 0:N KonfiguracniTemplate (switchport always references a KonfiguracniTemplate; a KonfiguracniTemplate MAY BE referenced zero or more times)
Switchport has FK konfiguracniTemplateAccess_id for this relation.
In .../model/Switchport.java the relation is mapped just like all other relations that are working:
#ManyToOne
#JoinColumn(nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
I have tried various forms:
#ManyToOne
#JoinColumn(name="konfiguracnitemplateaccess_id", nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
or
#ManyToOne(targetEntity=KonfiguracniTemplate.class)
#JoinColumn(name="konfiguracnitemplateaccess_id", nullable = false)
private KonfiguracniTemplate konfiguracniTemplateAccess;
I have also checked:
both entities are in the same package
they are both annotated "#Entity" using "import javax.persistence.Entity;"
the build produces no error/warning messages
as long as the reference in Switchport is commented out, everything is fine
No matter what I try I cannot get rid of the "references an unknown entity" exception. Can somebody please share an idea what is happening or maybe how to debug the issue? The stacktrace at the top of the post is all I get in the logs.
All input is greatly appreciated!
Just add the class Team to the "hibernate-cfg.xml" file, because Hibernate doesn't identify without adding into it.
Possible Solutions:
1) Ensure that the entity has been appropriately referenced in hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
...
<mapping class="com.project.entitytwo.model.EntityTwo"/>
...
</session-factory>
2) Ensure that #Entity has been specified at the class-level ( at the top of the class )
#Entity
#Table( name="ENTITY_TWO" )
public class EntityTwo extends AnyClass
{
...
I just had this problem, with entity a referencing entity b. Both entities were located in a common JAR outside of the web project I was working on; a was declared in persistence.xml but b wasn't. I put b in a <class> tag in persistence.xml and it worked!
I ran into this problem when using Spring and not using the hibernate.cfg.xml file. It was solved by adding the fully qualified package name of the Model class to the setPackagesToScan method of LocalSessionFactoryBean class.
Finally got the solution from another developer on the team!
The classes need to be imported before the SessionFactory object is created. Here the import for the new class was missing, so it was unknown to the SessionFactory object.
Anyway, thanks everyone for your hints!
There is one more chance of getting such exception; when you don't mention your mapping class in hibernate.cfg.xml file.
As mentioned above.
I had same exception... I just forget add annotation (#Entity, and #Table) on MASTER class(class with Primary key)
so solution is double check every annotation in your entities , I mean not only #ManyToOne and #OneToMany like i did.
if your two entity in diffrent project,you can scan KonfiguracniTemplate's package in other project.you can do like this in spring boot
#EntityScan({"com.thispackage.entity","com.KonfiguracniTemplatepackage.entity"})
I'll give you a solution that should work for the same error with Spring Boot. This has less to do with the original question, but today, people would probably look for this answer instead because noone uses XML configuration today anymore.
I suffered the same problem and found the solution on this website: https://www.programmersought.com/article/1617314625/
He even describes this very question he would have looked up, but then I'm asking myself: why didn't he answered here after finding the solution? LOL
His own words:
In the Spring Boot project, the default scan package is the package where the main method is located, that is, only the entity classes in the same package as the main method will be discovered. This way you can understand why User is not found: because User is an entity class in another module. Spring Boot does not scan other packages at all;
Configure the #SpringBootApplication annotation on the main method that launches the application, telling Spring Boot that those packages need to be scanned: #SpringBootApplication(scanBasePackages = {“com.xiaomo.*”})
Then, User can be found.
So you basically reconfigure SpringBoot to scan more packages to include the other ones.
My personal addition: you could also move your packages into the package where the starter is located or move the starter a package up (that's what I did).
I have a legacy application that uses hibernate for mapping objects into a database. It uses the Hibernate Mapping XML file to do so. The java class contains two properties abc and def that implement java Serializable. The mapping is defined this way:
<property name="abc" column="ABC" type="serializable" length="32672"/>
<property name="def" column="DEF" type="serializable" length="32672"/>
When I try to set this up with oracle, I get a nasty error "ORA-01754: a table may contain only one column of type LONG" which essentially is complaining about creating two 'long raw' columns in one table. Oracle does not like this. After reading up on the issue, the recommended approach is to use blobs instead of 'long raw' types.
My question is, how can I express in the hibernate mapping file to use a serializable type mapped into a blob column? I would think there would be a serializable_blob type but there does not seem to be.
I know this is possible with JPA annotations using #Basic and #Lob. It should also be possible using the hibernate mapping file. How can this be done in the hibernate mapping file?
Update:
The following do not work as Serializable works:
type=binary - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
type=blob - - This one expects a java.sql.Blob. Does not work for Serializable classes. Gives ClassCastException.
type=materialized_blob - - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
<property
name="data"
type="blob"
column="DATA"/>
...
should work.
Ok, did some more research following my comment above and, by Jove, I found it.
In Hibernate 3.5 + Spring 3.1, I used Spring's org.springframework.orm.hibernate3.support.BlobSerializableType. Now I'm upgrading to Hibernate 4.3, that option isn't available anymore. I did find the type to column mappings as OP, but in my application there are various Strings (legacy) that are mapped to BLOB fields.
So, as I reported in the comment above, I found the org.hibernate.type.SerializableToBlob type, which is parameterize. Below how I got the mapping to work (using good old-fashioned hbm.xml mappings)
<property name="description" column="TEXT">
<type name="org.hibernate.type.SerializableToBlobType">
<param name="classname">java.lang.String</param>
</type>
</property>
And that appears to do the trick. (the classname value should be the type of the attribute you are mapping, I think)
Hey people, i have a the following map* which is giving me lots of trouble:
Map<MetricSourceInterface, AliasesInterface>
MetricSourceInterface is an entity with simple properties.
AliasesInterface is an entity with only an Id and a list of strings.
Hibernate is creating the database schema so theres no problem with changing it whatsoever.
On a side-note, this is a sub problem from trying to map:
Map<MetricSourceInterface, List<String>>
Does anyone know the proper way to solve this?
Theres only one limitation for this, i dont want to create an UserType for AliasesInterface or List
Thx in advance :)
*edited with pstanton's correction :)
As long as AliasesInterface is indeed an entity in Hibernate sense, there's really no problem with mapping this:
#OneToMany(targetEntity=AliasInterface.class)
#MapKeyManyToMany(targetEntity=MetricSourceInterface.class, joinColumns=#JoinColumn(name="metric_source_id"))
private Map<MetricSourceInterface, AliasesInterface> myMap;
Note that the above assumes that both AliasInterface and MetricSourceInterface are entities; if they are indeed interfaces you'll need to refer to their concrete implementations instead.
Keep in mind that #MapKeyManyToMany is Hibernate extesion to JPA. More details / examples on mapping collections are in Hibernate docs.
Update: The same approach using XML mapping files:
<map name="myMap">
<key column="owner_id"/> <!-- FK to owner entity table -->
<map-key-many-to-many column="metric_source_id" class="MetricSourceInterface"/>
<one-to-many class="AliasesInterface"/>
</map>
There are more details here and other examples here.