JPA OneToMany Association from superClass
Asked Answered
H

1

4

I’m trying to map the inheritance from the superclass LendingLine and the subclasses Line and BlockLine. LendingLine has an ManyToOne association with Lending.

When I try to get the LendingLines from the database without the inheritance it works fine. The association works also. But when i add the inheritance, lendingLines in Lending is empty. I also can't get any LendingLines from the DB with the inheritance.

Can anybody help me?

(Sorry for the bad explanation)

Thanks in advance!

LendingLine:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE")
@DiscriminatorValue(value="Line")
@Table(name = "LendingLine")
public class LendingLine {
...
public LendingLine(){}
@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER, targetEntity=Lending.class)
@JoinColumn(name = "LendingId")
private Lending lending;
...

Lending:

@Entity
@Table(name = "Lending")
public class Lending {
...
public Lending(){}

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER, mappedBy = "lending")
private List<LendingLine> lendingLines;
...

BlockDate:

@Entity
@DiscriminatorValue(value = "BlockLine")
public class BlockLine extends LendingLine {
public BlockLine(){
}
}

LendingLineRepository:

This class only reads from the db because the db was created by another application ( C#) where the objects are added to the db.

public class LendingLineRepository extends JpaUtil implement LendingLineRepositoryInterface {
@Override
protected Class getEntity() {
    return LendingLine.class;
}

@Override
public Collection<LendingLine> findAll() {
    Query query = getEm().createQuery("SELECT l FROM LendingLine l");
    System.out.println(query.getResultList().size());
    return (Collection<LendingLine>) query.getResultList();
}

Table LendingLine:

enter image description here

Humphreys answered 27/4, 2016 at 10:29 Comment(8)
Why do you need @JoinColumn annotation in the @OneToMany mapping? As far as I can see, you are having a bidirectional relationship b/n Lending and LendingLine. Why do you need @JoinColumn annotation in the @OneToMany mapping?Carrell
@ujulo I don't know why the joinColumn was there but I removed it. It still doesn't work though. Thanks for the comment!Skelton
Is @Entity annotation not missing in Lending?Carrell
@Carrell Thanks I forgot to add it in my question.Skelton
can you post your code where you persist the lendingLines List?Casto
@Casto I added the LendingLineRepository but it doesn't write data(it happens in another application). do I need to post other information (like tables of the db...)? Thanks in advance!Skelton
I think you need to use @Inheritance annotation with sub classes too.Katiakatie
@chsdk Sorry but that doesn't work. I also haven't done it at my other inheritance and it works fine.Skelton
H
9

Choose your type of superclass according to your needs:

Concrete Class

public class SomeClass {}

Define your superclass as a concrete class, when you want to query it and when you use a new operator for further logic. You will always be able to persist it directly. In the discriminator column this entity has it's own name. When querying it, it returns just instances of itself and no subclasses.

Abstract Class

public abstract class SomeClass {}

Define your superclass as an abstract class when you want to query it, but don't actually use a new operator, because all logic handled is done by it's subclasses. Those classes are usually persisted by its subclasses but can still be persisted directly. U can predefine abstract methods which any subclass will have to implement (almost like an interface). In the discriminator column this entity won't have a name. When querying it, it returns itself with all subclasses, but without the additional defined information of those.

MappedSuperclass

@MappedSuperclass public abstract class SomeClass {}

A superclass with the interface @MappedSuperclass cannot be queried. It provides predefined logic to all it's subclasses. This acts just like an interface. You won't be able to persist a mapped superclass.

For further information: JavaEE 7 - Entity Inheritance Tutorial


Original message

Your SuperClass LendingLine needs to define a @DiscriminatorValue as well, since it can be instantiated and u use an existing db-sheme, where this should be defined.

Hadik answered 27/4, 2016 at 15:31 Comment(7)
I don't think that’s the case. I’ve tried it but the outcome doesn’t change. But thanks for the anser!Skelton
well, as far as i understand you, you can't query LendingLine as soon as you add the interface @Inheritance to this entity. is that right? can u provide the table-definition of LendingLine plz? since u defined the inheritance-strategy as single-table, that would be the most interesting thing.Hadik
Yes that’s correct. I added the table from LendingLine. .(Note: I can't change the DB because it is created by another application) Thanks in advance!Skelton
Ok, u provided the table, but quite incomplete. To clarify the entity-structure, we need to have more information. From the table you are providing, the superclass LandingLine seems to be an abstract class with the subclasses BreakLine and Line.Hadik
I clarified my original answer. Choose your case and then define your superclass according to your needs. If the existing db-sheme is consistent, then u won't have trouble to define your jpa-entities.Hadik
Thanks the information, it was very useful. I changed my classes and deleted the class line because there was no additional information in it compared to LendingLine. When I now try to get LendingLines from the database it only gives me the LendingLines but not the BlockLines.Skelton
Cheers mate, glad i could helpHadik

© 2022 - 2024 — McMap. All rights reserved.