I have simple JPA Entity.
@Entity
@Table(name = "channels")
public class Channel {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "channels_sequence")
@SequenceGenerator(name = "channels_sequence", allocationSize = 1)
private Long id;
@Column(name = "unique_id", unique = true, nullable = false)
private Long uniqueId;
@Column(name = "string_key", unique = true, nullable = false)
private String key;
public Channel(Long uniqueId, String key) {
this.uniqueId = uniqueId;
this.key = key;
}
protected Channel(){} // JPA
// setters, getters, equals, hashCode and toString...
}
Fields unique_id and string_key are unique for the entire table (unique = true). If I try to create an entity in violation of uniqueness in my Application class, an exception will be thrown, this is ok.
@SpringBootApplication
public class Application {
@Autowired
private ChannelRepository repository;
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.run(args);
}
@Bean
public CommandLineRunner run() {
return (args) -> {
Channel first = repository.save(new Channel(10L, "first"));
// Channel{id=1, uniqueId=10, key='first'}
System.out.println(first);
// ERROR: duplicate key value violates unique constraint "uk_xxx"
Channel second = repository.save(new Channel(10L, "second"));
System.out.println(second);
};
}
}
However, if I do the same in a unit test (JUnit 5), then the uniqueness constraints are ignored.
@DataJpaTest
class ChannelRepositoryTest {
@Autowired
private ChannelRepository repository;
@Test
void saveNewObjects() {
Channel first = repository.save(new Channel(1L, "first"));
Channel second = repository.save(new Channel(1L, "second"));
System.out.println(first);
System.out.println(second);
// Channel{id=1, uniqueId=1, key='first'}
// Channel{id=2, uniqueId=1, key='second'}
// where is exception??
}
}
I use PostgreSQL 13, my application.properties is:
spring.datasource.url = jdbc:postgresql://localhost:5432/mydb
spring.datasource.driver-class-name = org.postgresql.Driver
spring.datasource.username = root
spring.datasource.password = password
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQL10Dialect
spring.jpa.properties.hibernate.ddl-auto = create-drop
spring.jpa.properties.hibernate.show_sql = false
My ChannelRepository is simple inheritance from CrudRepository without new methods