euraad
euraad

Reputation: 2856

Why can't I insert a row into my database when I use @ManyToOne?

I have these entities.

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Language {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @NotNull
    private String language;
    
}

And

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sentence {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @NotNull
    private String wordInFrench;
    
    @NotNull
    private String wordInOtherLanguage;
    
    @ManyToOne
    @NotNull
    private Language language;
    
}

When I try to insert a row into the sentence database by using this code:

// My repository
private SentenceRepository sentenceRepository;

// Object information
Long id = 0L; 
String wordInFrench = "Oui oui"
String wordInOtherLanguage = "Ja ja"
Language language = new Language(id, "Swedish");

// Save to database
sentenceRepository.save(new Sentence(id, wordInFrench, wordInOtherLanguage, language));

I get this error:

org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find 
    se.danielmartensson.entity.Language with id 0; nested exception is javax.persistence.EntityNotFoundException: Unable to find se.danielmartensson.entity.Language with id 0

    Caused by: javax.persistence.EntityNotFoundException: Unable to find se.danielmartensson.entity.Language with id 0

And if I use Long id = 1L; then I get this error as well:

org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find 
se.danielmartensson.entity.Language with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find se.danielmartensson.entity.Language with id 1

Caused by: javax.persistence.EntityNotFoundException: Unable to find se.danielmartensson.entity.Language with id 1

So what is happening? Why can't I insert a sentence into the database and the language database will updates as well?

Upvotes: 0

Views: 647

Answers (1)

Guilherme Barboza
Guilherme Barboza

Reputation: 652

The problem is that Hibernate is trying to find a Language instance in the database with id = 0 (and 1), but it isn't there.

First you must insert the Language and only after this you can insert the Sentence:

// My repositories
private LanguageRepository languageRepository;
private SentenceRepository sentenceRepository;

// Inserting the Language
Language language = new Language();
language.setLanguage("Swedish");
// Here, note that I'm not forcing the value of the attribute "id". 
// The "@GeneratedValue" will generate one for me.

// Also note that the "save" method returns an object. In this case, 
// it will be a "Language" instance with the new id
language = languageRepository.save(language);

// Inserting the Sentence
Sentence sentence = new Sentence();
sentence.setWordInFrench("Oui oui");
sentence.setWordInOtherLanguage("Ja ja");
sentence.setLanguage(language);

sentenceRepository.save(sentence);  

Anternatively, you can do:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sentence {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @NotNull
    private String wordInFrench;
    
    @NotNull
    private String wordInOtherLanguage;
    
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "id_language", nullable = false)
    private Language language;

We're using cascade = CascadeType.PERSIST to indicate that, every time we try to insert a new Sentence, Hibernate will automatically check if the language object is already present in the database. If not, the language will be inserted beforehand. Besides, for foreign keys, it's suggested to use the @JoinColumn Mapping to configure the column definitions like "name", "nullable", "unique", etc.

Upvotes: 1

Related Questions