Integration test fail with ConstraintViolationException when User is used twice
See original GitHub issueOverview of the issue
In UserResourceIntTest
the default login is johndoe
but because the login must be unique, creating a domain object with two relations on User fails with a ConstraintViolationException
.
Motivation for or Use Case
The UserResourceIntTest
sets the default login to a fix value (johndoe
):
public class UserResourceIntTest {
private static final String DEFAULT_LOGIN = "johndoe";
}
Login has a unique constraint defined in the Liquibase file (unique="true"
):
<column name="login" type="varchar(50)">
<constraints unique="true" nullable="false"/>
</column>
So when you have a domain that is related twice (indirectly) to User, two users johndoe
are created, therefore, there is a ConstraintViolationException
Reproduce the error
Take a JHipster monolith and import the following JDL. Because we can’t add extra information on User
, here, I’ve created a Representative
that has a one to one relation to User
. Now, let’s say that an Invoice
is signed by a Representative
(a User
), an Invoice
is related to a Contract
, which can be signed by a different Representative
.
entity Contract {
price Integer,
discountRate Float,
vatRate Float,
nbTicketsAttendee Integer,
nbTicketsExhibitor Integer,
additionalInformation String
createdOn Instant
}
entity Invoice {
limitPaymentDate LocalDate,
}
entity Representative {
phoneArea String,
phoneNumber String
}
relationship ManyToOne {
Invoice{representativeSigning(lastName) required} to Representative,
Contract{representativeSigning(lastName) required} to Representative
}
relationship OneToOne {
Representative{user(lastName) required} to User
}
relationship OneToMany {
Contract{invoices} to Invoice{contract required}
}
The InvoiceResourceIntTest
creates an invoice, creates and persists the representative for the invoice (therefore, one johndoe
), creates and persists the representative of the contract (that is the second johndoe
).
Suggest a Fix
Because the login must be unique, instead of setting a fix value, it should be a random string. So, instead of:
public static User createEntity(EntityManager em) {
User user = new User();
user.setLogin(DEFAULT_LOGIN);
user.setPassword(RandomStringUtils.random(60));
...
return user;
}
It could be something like
public static User createEntity(EntityManager em) {
User user = new User();
user.setLogin(DEFAULT_LOGIN + RandomStringUtils.random(10));
user.setPassword(RandomStringUtils.random(60));
...
return user;
}
And, instead of checking that the login is equal to johndoe
:
assertThat(testUser.getLogin()).isEqualTo(DEFAULT_LOGIN);
Maybe just check that it’s starts with johndoe
:
assertThat(testUser.getLogin()).startsWith(DEFAULT_LOGIN);
Using JHipster version installed locally in current project’s node_modules Executing jhipster:info Options:
JHipster Version(s)
sponsors@0.0.0 /Users/agoncal/Documents/Code/Temp/jhipster/sponsors
└── generator-jhipster@4.9.0
JHipster configuration, a .yo-rc.json
file generated in the root folder
.yo-rc.json file
{ "generator-jhipster": { "promptValues": { "packageName": "io.quantixx.sponsor" }, "jhipsterVersion": "4.9.0", "baseName": "sponsors", "packageName": "io.quantixx.sponsor", "packageFolder": "io/quantixx/sponsor", "serverPort": "8080", "authenticationType": "jwt", "hibernateCache": "ehcache", "clusteredHttpSession": false, "websocket": false, "databaseType": "sql", "devDatabaseType": "postgresql", "prodDatabaseType": "postgresql", "searchEngine": false, "messageBroker": false, "serviceDiscoveryType": false, "buildTool": "maven", "enableSocialSignIn": false, "enableSwaggerCodegen": false, "jwtSecretKey": "replaced-by-jhipster-info", "clientFramework": "angularX", "useSass": false, "clientPackageManager": "yarn", "applicationType": "monolith", "testFrameworks": [], "jhiPrefix": "jhi", "enableTranslation": false } }
JDL for the Entity configuration(s) entityName.json
files generated in the .jhipster
directory
JDL entity definitions
entity Contract (contract) { price Integer, discountRate Float, vatRate Float, nbTicketsAttendee Integer, nbTicketsExhibitor Integer, additionalInformation String, createdOn Instant } entity Representative (representative) { phoneArea String, phoneNumber String } entity Invoice (spn_invoice) { limitPaymentDate LocalDate } relationship OneToOne { Representative{user(lastName) required} to User } relationship OneToMany { Contract{invoices} to Invoice{contract required} } relationship ManyToOne { Contract{representativeSigning(lastName) required} to Representative, Contract{representativeAccepting(lastName) required} to Representative, Invoice{representativeSigning(lastName) required} to Representative }
Environment and Tools
java version “1.8.0_131” Java™ SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot™ 64-Bit Server VM (build 25.131-b11, mixed mode)
git version 2.14.2
node: v8.7.0
npm: 5.4.2
bower: 1.8.0
gulp: [16:58:25] CLI version 1.3.0
yeoman: 2.0.0
yarn: 1.2.1
Docker version 17.09.0-ce, build afdb6d4
Issue Analytics
- State:
- Created 6 years ago
- Comments:16 (16 by maintainers)
@cbornet that was short and concise 😄 👍 I just cahnge the code to use a
randomAlphabetic
with a size of five.@duderoot simpler, less code