0

This is my sql table structure:

create table TBL_EMPLOYEE_FIVE(
    EMP_ID integer generated always as identity(start with 50, increment by 4),
    NAME varchar(50),
    COUNTRY varchar(50),
    MGR_ID integer,
    MGR_COUNTRY varchar(50),
    constraint PK_COMPOSIT_001AD primary key(EMP_ID,COUNTRY),
    constraint  FK_COMPO_00123 foreign key(MGR_ID,MGR_COUNTRY) references TBL_EMPLOYEE_FIVE
)

And this is my entity mapping:

@Entity
@Table(name="TBL_EMPLOYEE_FIVE")
@IdClass(EmployeeId.class)
public class EmployeeOne implements Serializable{

    public EmployeeOne(){}
    public EmployeeOne(String employeeName,String empCountry){
        this.empCountry = empCountry;
        this.employeeName = employeeName;
    }

    public EmployeeOne(String employeeName,String empCountry,EmployeeOne manager){
        this.empCountry = empCountry;
        this.employeeName = employeeName;
        this.manager = manager;
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="EMP_ID")
    private Integer employeeId;

    @Id
    @Column(name="COUNTRY")
    private String empCountry;

    @Column(name="NAME")
    private String employeeName;

    @ManyToOne( cascade= {CascadeType.PERSIST, CascadeType.PERSIST},
            fetch= FetchType.LAZY,
            targetEntity=EmployeeOne.class)
            @JoinColumns({
            @JoinColumn(name="MGR_ID",referencedColumnName="EMP_ID"),
            @JoinColumn(name="MGR_COUNTRY",referencedColumnName="COUNTRY")
    })
    private EmployeeOne manager;

    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.PERSIST},mappedBy="manager")
    private Set<EmployeeOne> employees;
// getters and setters,
}

This is the the embedded id mapping,

@Embeddable
public class EmployeeId implements Serializable{

    public EmployeeId(){}

    public EmployeeId(Integer employeeId,String empCountry){
       this.employeeId = employeeId;
       this.empCountry = empCountry;
    }

    @Column(name="EMP_ID")
    private Integer employeeId;

    @Column(name="COUNTRY")
    private String empCountry;
// only getters and implementation of hashcode and equals method
}

And this is what I am trying to run in my main method:

EmployeeOne manager = new EmployeeOne("Yousuf Ahmadinejad", "IRAN");
em.persist(manager);

But here i am getting an exception i.e.

Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Attempt to modify an identity column 'EMP_ID'. 

It's not like i didn't understood the exception,

but why this exception occured in the first place? I already annotated it with @GenerateValue for Empid and I am not setting the empId manually. Does this exception occur because I have combined primary key as empId and country, and than the empId is autogenerated using Identity, hence its giving an exception ?

Can you please tell me whats going wrong

One more thing i want to add here is, if i removed @Column and @Embeddeble annotation for EmployeeId.java, and than run, i get an following exception,

Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.entities.derived.EmployeeId.employeeId

So just trying to find the solution to persist employee keeping the autogenerated Id as it is

Franz Kafka
  • 10,623
  • 20
  • 93
  • 149
Rahul Shivsharan
  • 2,481
  • 7
  • 40
  • 59
  • Not sure, but it seems wierd to both specify `EMP_ID` in your main class aswell as in the embedded class. If you use hibernate to reverse engineer the entity from the database, maybe that could give you an idea on how to map it? – Magnilex Apr 10 '13 at 13:34
  • actually i edited the create table query, i removed the identity from emp_id attribute, and the same change i did to entity, but also i added a method annotating with @PrePersist. This method has a JPQL query to fetch the max of employee and than increment the count and set it in the setter of employeeId, and than it worked. But this solution is a manual stuff, and not feasible also. I want a good solution so that i don't have to remove the identity. – Rahul Shivsharan Apr 10 '13 at 13:53

1 Answers1

0

First Hibernate does not generate id's for composite keys, so you should change EmployeeOne to:

@Id
//@GeneratedValue(strategy=GenerationType.IDENTITY) remove this line
@Column(name="EMP_ID")
private Integer employeeId;

Second that's not how you should implement EmployeeId composite key class. See: https://stackoverflow.com/a/3588400/1981720

Third, the exception is thrown by the database, not Hibernate. Check if you're getting the same exception with another database.

Community
  • 1
  • 1
lunr
  • 5,159
  • 4
  • 31
  • 47