1

Have a Spring boot with Spring Data JPA. Postgres DB.

General entity:

@Entity
@Table
class Entity {

@Id
@GeneratedValue
private int id;

}

when I try to make an entry with a specified id value, as a result I see that it is ignored and generated by @GeneratedValue.

How to overcome this?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Draaksward
  • 759
  • 7
  • 32
  • Are you using a jpa repository or crud ? – Sunshine Apr 02 '20 at 10:52
  • Going by the flow of CRUD repo – Draaksward Apr 02 '20 at 10:53
  • try to make your repository inherit from JpaRepository – Sunshine Apr 02 '20 at 10:54
  • Check this it might help..https://stackoverflow.com/questions/89439/bypass-generatedvalue-in-hibernate – Reeta Wani Apr 02 '20 at 10:59
  • @Yosra, tried. Same – Draaksward Apr 02 '20 at 11:03
  • @ReetaWani, running a fresh db with all possible sequences cleaned up and etc + trying different generation strategies. No luck. – Draaksward Apr 02 '20 at 11:03
  • Try doing this `@GeneratedValue(generator = "org.hibernate.id.Assigned")` – Sunshine Apr 02 '20 at 11:18
  • Assigned is the default generator strategy if there is no element . In this case, application assigns the id. AppleBuckler if you remove "@GeneratedValue" then it will work and assign user given ID. But i don't think you need that.. – Reeta Wani Apr 02 '20 at 11:31
  • "org.hibernate.id.Assigned" on this I get a `Could not instantiate id generator`. – Draaksward Apr 02 '20 at 11:33
  • @ReetaWani, yes, that's the thing I'm trying to handle - have a GeneratedValue when the ID is null/0, and use the provided when there is one. – Draaksward Apr 02 '20 at 11:34
  • try to inspire from this answer by personalizing its add function by generating random id if it's not provided. https://stackoverflow.com/a/52010963/13101111 – Sunshine Apr 02 '20 at 11:43
  • well, the ID is used not only for row identification, so making it as UUID isn't a possibility – Draaksward Apr 02 '20 at 11:46
  • Thanks all for the input. After doing some good old debug the whole thing investigation, I've struck on many interesting things like "it's merged by default", "no persistantId at all" and "SequenceGenerator ignores the provided entity to persist" I went the road of GenericGenerator and it works quite well. – Draaksward Apr 02 '20 at 13:25
  • Could you make the final comment a proper answer, so others see this is answered? – Jens Schauder Apr 02 '20 at 14:43
  • Sure. Not sure though if the solution is the one, which is intended to be... – Draaksward Apr 03 '20 at 07:51

1 Answers1

2

Posting the solution, to which I came after doing a debug of the whole persist process (not stating that this is the right way, but I literally didn't find any spot of "maybe I configured something wrong"):

public class MyGenerator extends SequenceStyleGenerator {

    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
        return Optional.of(object)
                .filter(Entity.class::isInstance)
                .map(Entity.class::cast)
                .map(Entity::getId)
                .filter(i -> i > 0)
                .map(Serializable.class::cast)
                .orElseGet(() -> super.generate(session, object));
    }
)

and the entity:

@Entity
class Entity implements Serializable {

@GenericGenerator(name = "myGenerator", strategy = "org.a.b.c.generators.MyGenerator")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "myGenerator")
    private Integer id;

}
zouabi
  • 649
  • 1
  • 7
  • 16
Draaksward
  • 759
  • 7
  • 32