user2270145
user2270145

Reputation: 3

JPA OneToMany using Inheritance

I have the following classes:

Hardware.java

    @Entity
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    public class Hardware{
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE)
    private long id;
    private String serialnumber;    

    @OneToMany (mappedBy="hardware")
    private List<Equipment> equipments;
}

Computer.java

    @Entity
    public class Computer extends Hardware {

    private String hostname;
    private String macAdress;
    private String ipNumber;

    public Computer(){
        super();
    }

    public Computer(String serialnumber, String hostname,
        String macAdress, String ipNumber) {
        super(serialnumber);
        this.hostname = hostname;
        this.macAdress = macAdress;
        this.ipNumber = ipNumber;
    }
}

NetworkDeivce.java

    @Entity
    public class NetworkDevice extends Hardware {

    private String hostname;
    private String ipAdress;

    public NetworkDevice(){
        super();
    }

    public NetworkDevice(String serialnumber, String hostname,
            String ipAdress) {
        super(serialnumber);
        this.hostname = hostname;
        this.ipAdress = ipAdress;
    }
}

And now the class that is mapped to the Hardware Class:

Equipment.java

@Entity
public class Equipment {

    public Equipment(){
    }
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    private String serialnumber;
    private String info;

    @ManyToOne (fetch=FetchType.EAGER)
    @JoinColumn(name="HW_ID")
    private Hardware hardware;
}

Now if I add a Equipment to a Computer it all works finde, but if I try to add Equipment to a NetworkDevice I get this Error: Internal Exception:

Internal Exception:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
Error Code: 1452
Call: INSERT INTO EQUIPMENT (INFO, SERIALNUMBER, HW_ID) VALUES (?, ?, ?)
    bind => [3 parameters bound]
Query: InsertObjectQuery(domain.hardware.Equipment@600a620d)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
    at main.dbTest(main.java:74)
    at main.main(main.java:18)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
Error Code: 1452
Call: INSERT INTO EQUIPMENT (INFO, SERIALNUMBER, HW_ID) VALUES (?, ?, ?)
    bind => [3 parameters bound]
Query: InsertObjectQuery(domain.hardware.Equipment@600a620d)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:851)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:913)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`inventorytool_beta`.`EQUIPMENT`, CONSTRAINT `FK_EQUIPMENT_HW_ID` FOREIGN KEY (`HW_ID`) REFERENCES `COMPUTER` (`ID`))
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

So I think it's a problem with the inheritance... I'm not very good at JPA..

Thanks in advance.

Upvotes: 0

Views: 406

Answers (3)

Gab
Gab

Reputation: 8323

Yes it comes from your inheritance strategy. You can't use @GeneratedValue(strategy=GenerationType.IDENTITY) with table_per_class.

See Java/Hibernate JPA: InheritanceType.TABLE_PER_CLASS and IDs

Upvotes: 0

WilQu
WilQu

Reputation: 7383

Have a look at the schema that was generated. You should had three different tables for hardware, due to your inheritance strategy: one for Hardware, one for Computer and one fon NetworkDevice. The problem is that HW_ID can only reference one table. Here your JPA provider chose Computer, probably because it's first in alphabetical order, but it can't handle all three classes.

Consider using another inheritance strategy, like JOIN.

Upvotes: 1

Ravi Trivedi
Ravi Trivedi

Reputation: 2360

Check the code where you insert Equipment to a NetworkDevice. It looks like HW_ID does not exists in the master-table(Hardware). Because it is trying to insert nonexistent Master-Table HW_ID as foreign-Key in child table(Equipment).

Regards, Ravi

Upvotes: 0

Related Questions