0
votes

Setup: Sprting, JPA and Hibernate as JPA provider.

We have two class hierarchies, one for questions and other one for answers. At the root of each hierarchy there is an abstract class, for example:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class QuestionUnit {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;
    @OneToOne(cascade = CascadeType.ALL)
    private AnswerUnit correctAnswer;

    public QuestionUnit(AnswerUnit correctAnswer) {
        this.correctAnswer = correctAnswer;
    }

    public void setCorrectAnswer(AnswerUnit correctAnswer) {
        this.correctAnswer = correctAnswer;
    }

    public AnswerUnit getCorrectAnswer() {
        return this.correctAnswer;
    }

    public int getId() {
        return id;
    }

    public abstract Object getQuestionContent();
}

and

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AnswerUnit {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private int id;

    public abstract Object getAnswerContent();

    public abstract boolean isEqual(AnswerUnit otherAnswer);

    public int getId(){
        return id;
    }
}

in each hierarchy there are 3 concrete classes. We wanted to store them in database, for now we are using SQLite.

If I understand correctly this Inheritance strategy will create one table per concrete class.

Now, when I set up GeneratedValue strategy at auto I got errors, so I switched it to table. If I understand it correctly, for each table there will be different independent generation of ids.

But something strange happened. I created simple testing code:

QuestionUnit unit1=new OpenQuestion("4+4", new OpenQuestionAnswer("8"));
questionUnitDao.addQuestionUnit(unit1);
System.out.println(questionUnitDao.getQuestionUnit(OpenQuestion.class, 1).getQuestionContent());

the first question was inserted succesfully, but then I got an error that primary key should be unique, now when I insert something I get very large numbers as ids, for example 65536.

Why is it?

1
About the big generated id's, see this question - siebz0r
Thanks or link, it is because Hilo algorithm used for id generation. - Andna
what's the error when you set it to AUTO? Also note that using primitive types as IDs is discouraged. - Istvan Devai
@IstvanDevai: Why is using primitive types as IDs discouraged? - Tom Anderson
Because a primitive cannot have a null value, where as Object's can. A null id value is how Hibernate will determine (by default) whether an object has been persisted or not. - Brad

1 Answers

0
votes

You can add TableGenerator annotation in your both entities.See sample;

  @Id
  @TableGenerator(name = "QuestionUnitGen",
  table = "ID_GEN",
  pkColumnName = "GEN_NAME", 
  pkColumnValue = "QuettionUnit_Gen", 
  valueColumnName = "GEN_VAL", 
  initialValue = 0,
  allocationSize = 100
  )
  @GeneratedValue(strategy = GenerationType.TABLE, generator = "QuestionUnitGen")
  private int id;

But don't forget to create ID_GEN table with two fields GEN_NAME and GEN_VAL in your database.