Spring Data JPA - объекты с составным ключом, в которых один столбец является внутренней последовательностью, связанной с другим - PullRequest
0 голосов
/ 09 января 2020

У меня есть таблица, подобная следующей в базе данных Oracle:

| GROUP | SEQ | OTHER_DATA |
|-------|-----|------------|
| 1     | 1   | ~~~~~~~~~~ |
| 1     | 2   | ~~~~~~~~~~ |
| 1     | 3   | ~~~~~~~~~~ |
| 2     | 1   | ~~~~~~~~~~ |
| 2     | 2   | ~~~~~~~~~~ |
| 2     | 3   | ~~~~~~~~~~ |

, где GROUP - это внешний ключ, а (GROUP, SEQ) - это первичный ключ. Я хочу вставить следующую запись для группы 1, которая должна быть (1, <(MAX SEQ FOR GROUP 1) + 1>, <OTHER DATA>) = (1, 4, <OTHER DATA>).

. Я использую Spring Boot 2. Пока у меня есть следующее:

public class MyEntityPK implements Serializable {
    private Long group;
    private Long seq;
    // getters and setters ...
}

@Entity
@Table(name = "MY_TABLE")
@IdClass(MyEntityPK.class)
public class MyEntity {

    @Id
    private Long group;

    @Id
    private Long seq;

    @ManyToOne
    @JoinColumn(name="GROUP", insertable=false, updatable=false)
    private Group group;

    private String otherData;
    // getters and setters ...
}

public interface MyEntityRepository extends CrudRepository<MyEntity, MyEntityPK> {}

Когда я явно установите поле seq, как в следующем примере, все работает.

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyEntityTest {

    @Autowired
    MyEntityRepository repository;

    @Test
    public void testSaveMyEntityWithExplicitParameters() {
        MyEntity entity = new MyEntity();
        Group group = new Group(1L, "Group description");
        entity.setGroup(group);
        entity.setSeq(4L);
        repository.save(entity);
    }
}

Но я не могу понять, как увеличить последовательность в слое постоянства, не добавляя logi c в сервис, который использует MyEntityRepository, чтобы получить максимальное значение seq и явно установить его. Я не могу использовать @GeneratedValue с генератором последовательности, потому что он генерирует следующее доступное значение без учета группы.

1 Ответ

1 голос
/ 09 января 2020

в качестве предложения вы можете попробовать триггер, пожалуйста, найдите сырой пример:

CREATE OR REPLACE TRIGGER seq_upd_before_insert
BEFORE INSERT
   ON MY_TABLE
   FOR EACH ROW
DECLARE
   v_seq number;
BEGIN
   -- Find max seq for performing INSERT into your table
   SELECT max(seq) INTO v_seq 
   FROM MY_TABLE
   WHERE group = :new.group
   GROUP BY group;

   -- Update new seq field to max seq + 1 before insert
   :new.seq := v_seq + 1;
END;
/

Надеюсь, это поможет

...