In Vaadin 7, I'm trying to bind my ComboBox of phone numbers to a list of POJO nested in a POJO.
For exemple: I have PersonVo that contains a List phones; and PersonCommunicationVo contains the value of the phone number.
What I used for binding the others properties of PersonVo is:
BeanFieldGroup<PersonVo>personBinder = new BeanFieldGroup<PersonVo>(PersonVo.class);
personBinder.setItemDataSource(person);
myFormLayout.addComponent(personBinder.buildAndBind("Firstname", "firstName"));
myFormLayout.addComponent(personBinder.buildAndBind("Country", "country.name"));
Here PersonVo:
#Table(name = "CONTACT.T_PERSON")
#Entity
#Audited
public class PersonVo {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id",updatable = false)
private Long personId;
#Column(name = "FIRSTNAME")
private String firstName;
#Column(name = "LASTNAME")
private String lastName;
#Column(name = "TITLE")
private String title;
...
#OneToMany(fetch = FetchType.LAZY, mappedBy = "personId")
#AuditMappedBy(mappedBy = "personId")
private List<PersonCommunicationVo> **phoneNumbers**;
...
and PersonCommunicationVo:
#Entity
#Table(name = "CONTACT.PERSON_COMMUNICATION")
#Audited
public class PersonCommunicationVo {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id",updatable = false)
private Long persCommId;
#Column(name = "PERSON_ID")
private Long personId;
#ManyToOne
#JoinColumn(name = "COM_TYPE_ID")
private CommunicationTypesVo communicationType;
#Column(name = "VALUE")
private String **value**;
And what I would like to do is to bind my combobox of phone number to the list phoneNumbers from PersonVo based on the value from PersonCommunicationVo.
But the difficulty is to reach the right PersonCommunicationVo in the list base on what has been selected in the combobox. For exemple: I have selected the phone number +32 123 456 789 in the combobox and this value should be map to the phoneNumbers.get(indexOfSelectedItem).getValue().
In order to update the phone number, add a new one etc...
Thanks for the help!
maybe i didnt understand your datamodel, if so, could you please post PersonVo, PhoneVo(?) and PersonCommunicationVo and explain it a little further why you want to save it like you do. why does your personvo contain a List of phones? i've never worked with a beanfieldgroup before, but i think of something like:
ComboBox cb = new ComboBox("Phones", person.getPhones())
personBinder.bind(cb, "phones");
myFormLayout.addComponent(cb);
You can try something like this (java 1.7 syntax and Vaadin7):
...
FieldGroup fGroup = new FieldGroup( new BeanItem<PersonVo> (personInstance) );
...
BeanItemContainer<PersonCommunicationVo> numbers = new BeanItemContainer<>( PersonCommunicationVo.class );
numbers.addAll( personInstance.getPhoneNumbers() );
ComboBox phoneCombo = new ComboBox( "Phone Numbers", numbers );
phoneCombo.setItemCaptionMode( ItemCaptionMode.PROPERTY );
phoneCombo.setItemCaptionPropertyId( "**value**" );
fGroup.bind (phoneCombo, "**phoneNumbers**")
myFormLayout.addComponent(phoneCombo);
...
Related
Hello I am new to apex and soql, I would like some help on my test class, below is the code i am having trouble with,
public class UpdateMyCard {
#AuraEnabled(cacheable=false)
public static Card__c updateCard(Double Amount){
String userId = UserInfo.getUserId();
Card__c myCard = [SELECT Id, Card_no__c, total_spend__c From Card__c Where OwnerId =:userId];
myCard.total_spend__c = myCard.total_spend__c + Amount;
try{
update myCard;
}catch (Exception e) {
System.debug('unable to update the record due to'+e.getMessage());
}
return myCard;
}
}
Test Class
#isTest
public static void updatecard(){
UpdateMyCard.updateCard(200);
}
Error:
System.QueryException: List has no rows for assignment to SObject
Your code assumes there's already a Card record for this user. And it's exactly 1 record (if you have 2 your query will fail). I'm not sure what's your business requirement. Is it guaranteed there will always be such record? Should the code try to create one on the fly if none found? You might have to make that "updateCard" bit more error-resistant. Is the total spend field marked as required? Because "null + 5 = exception"
But anyway - to fix your problem you need something like that in the test.
#isTest
public static void updatecard(){
Card__c = new Card__c(total_spend__c = 100);
insert c;
UpdateMyCard.updateCard(200);
c = [SELECT total_spend__c FROM Card__c WHERE Id = :c.Id];
System.assertEquals(300, c.total_spend__c);
}
I have created a counterparty session, issuer signs the transaction by passing in its key to the signInitialTransaction. Then when I call the CollectSignaturesFlow to get the buyer's signature, it throws 'Unable to match key(s)' exception.
No idea what went wrong.
This is my initiator flow.
package com.template.flows;
#InitiatingFlow
#StartableByRPC
public class InitiateTicketMovementFlow extends FlowLogic<String> {
private final String buyer;
private final String issuer;
private final StateRef assetReference;
public InitiateTicketMovementFlow(String buyer, String issuer, String hash, int index) {
this.buyer = buyer;
this.issuer = issuer;
this.assetReference = new StateRef(SecureHash.parse(hash), index);
}
#Override
#Suspendable
public String call() throws FlowException {
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
AccountInfo issuerAccountInfo = UtilitiesKt.getAccountService(this)
.accountInfo(issuer).get(0).getState().getData();
AccountInfo receiverAccountInfo = UtilitiesKt.getAccountService(this)
.accountInfo(buyer).get(0).getState().getData();
AnonymousParty buyerAccount = subFlow(new RequestKeyForAccount(receiverAccountInfo));
QueryCriteria.VaultQueryCriteria queryCriteria = new QueryCriteria.VaultQueryCriteria()
.withStateRefs(ImmutableList.of(assetReference));
StateAndRef<CustomTicket> ticketStateStateAndRef = getServiceHub().getVaultService()
.queryBy(CustomTicket.class, queryCriteria).getStates().get(0);
CustomTicket ticketState = ticketStateStateAndRef.getState().getData();
TransactionBuilder txBuilder = new TransactionBuilder(notary);
MoveTokensUtilities.addMoveNonFungibleTokens(txBuilder, getServiceHub(),
ticketState.toPointer(CustomTicket.class), receiverAccountInfo.getHost());
FlowSession buyerSession = initiateFlow(receiverAccountInfo.getHost());
buyerSession.send(ticketState.getValuation());
List<StateAndRef<FungibleToken>> inputs = subFlow(new ReceiveStateAndRefFlow<>(buyerSession));
List<FungibleToken> moneyReceived = buyerSession.receive(List.class).unwrap(value -> value);
MoveTokensUtilities.addMoveTokens(txBuilder, inputs, moneyReceived);
SignedTransaction selfSignedTransaction = getServiceHub().
signInitialTransaction(txBuilder, ImmutableList.of(issuerAccountInfo.getHost().getOwningKey()));
SignedTransaction signedTransaction = subFlow(new CollectSignaturesFlow(
selfSignedTransaction, Arrays.asList(buyerSession), Collections.singleton(issuerAccountInfo.getHost().getOwningKey())));
SignedTransaction stx = subFlow(new FinalityFlow(
signedTransaction, ImmutableList.of(buyerSession)));
subFlow(new UpdateDistributionListFlow(stx));
return "\nTicket is sold to "+ buyer;
}
}
It SEEMS like the issue here is that you're getting the buyer account the wrong way? Or that the finality flow call might be off. Take a look at our samples on this.
Maybe try something like this to get your account info
AccountInfo targetAccount = accountService.accountInfo(<STRING NAME OF ACCOUNT >).get(0);
src is our corda samples repo: https://github.com/corda/samples-java/blob/master/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendShippingRequest.java#L80
Also, note how different the finality calls look like:
https://github.com/corda/samples-java/blob/master/Accounts/supplychain/workflows/src/main/java/net/corda/samples/supplychain/flows/SendShippingRequest.java#L112
I have two entities, TestCase and TestCaseStep, defined as follows:
TestCase
#Entity
#Table(name = "TEST_CASE")
public class TestCase implements Serializable, TestCase
{
#Id
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(name = "Testcase_Step_Association", joinColumns = { #JoinColumn(name = "TC_NAME", referencedColumnName = "NAME") }, inverseJoinColumns = {
#JoinColumn(name = "STEP_NAME", referencedColumnName = "NAME") })
#OrderColumn(name = "STEP_NUMBER", nullable = false)
private List<TestCaseStep> testCaseSteps;
[...]
}
TestCaseStep
#Entity
#Table(name = "TEST_CASE_STEPS")
public class TestCaseStep implements Serializable, TestCaseStep
{
#Id
#Column(name = "name")
private String name;
[...]
}
This works fine as long as I do not try to insert the same object into the list of test case steps more than once. As soon as I try that, I get a primary key violation:
Caused by: org.h2.jdbc.JdbcSQLException: Eindeutiger Index oder Prim�rschl�ssel verletzt: "PRIMARY_KEY_9 ON PUBLIC.TESTCASE_STEP_ASSOCIATION(TC_NAME, TESTCASESTEPS_NAME) VALUES ('TESTCASE_1', 'OUT_STEP', 395)"
Unique index or primary key violation: "PRIMARY_KEY_9 ON PUBLIC.TESTCASE_STEP_ASSOCIATION(TC_NAME, TESTCASESTEPS_NAME) VALUES ('TESTCASE_1', 'OUT_STEP', 395)"; SQL statement:
INSERT INTO Testcase_Step_Association (testCaseSteps_NAME, TC_NAME, STEP_NUMBER) VALUES (?, ?, ?) [23505-191]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.index.BaseIndex.getDuplicateKeyException(BaseIndex.java:107)
at org.h2.mvstore.db.MVSecondaryIndex.checkUnique(MVSecondaryIndex.java:230)
at org.h2.mvstore.db.MVSecondaryIndex.add(MVSecondaryIndex.java:189)
at org.h2.mvstore.db.MVTable.addRow(MVTable.java:704)
at org.h2.command.dml.Insert.insertRows(Insert.java:156)
at org.h2.command.dml.Insert.update(Insert.java:114)
at org.h2.command.CommandContainer.update(CommandContainer.java:98)
at org.h2.command.Command.executeUpdate(Command.java:258)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:160)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:146)
at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:125)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:892)
... 193 more
I need to allow my users to repeat the same test case step multiple times. How can I accomplish this without using a separate entity to map the relationship by myself?
Instead of defining name as a primary key in both TestCase and TestCaseSteps Entity,try to define a Surrogate Key as a primary key wherein you keep the Generation Strategy of that Surrogate Key to AUTO
In this way ,you always make a new Insert when you are rerunning test cases.
I am using embedded glassfish (3.1.2.2) with junit (4.11), with JDK 1.7, though my source and target is set to 1.6 (maven-compiler-plugin configuration).
Following is my code:
Person.java
#Entity
public class Person implements Serializable {
private static final long serialVersionUID = 81398385247591972L;
#Id
#GeneratedValue
private Long id;
#Version
private Long version;
#Column(length = 15, nullable = false, unique = true, updatable = false)
private String username;
#Column(length = 50)
private String status;
// Constructors
// getters/setters
// hashCode, equals, toString
}
Service.java
#Stateless
public class Service {
#PersistenceContext(unitName = "ExamplePU", type = PersistenceContextType.TRANSACTION)
private EntityManager em;
public Person add(Person person) {
em.persist(person);
return person;
}
public Person find(Long id) {
return em.find(Person.class, id);
}
public Person modify(Person person) {
return em.merge(person);
}
// some more code ...
}
ServiceTest.java
public class ServiceTest {
private static EJBContainer ejbContainer;
private static Service service;
// #BeforeClass, #AfterClass, #Before, #After
#Test
public void testMerge() {
Person person;
/* Step 1 */person = service.add(new Person("username", "status"));
print("Added : " + person);
person.setStatus("Away");
/* Step 2 */person = service.modify(person);
print("Merged (status change) : " + person);
person.setUsername("UsErNaMe");
/* Step 3 */person = service.modify(person);
print("Merged (username change) : " + person);
}
// Some more tests
}
Step 1 generates following SQL (as expected):
INSERT INTO PERSON (ID, STATUS, USERNAME, VERSION) VALUES (?, ?, ?, ?)
bind => [1, status, username, 1]
Step 2 generates following SQL (as expected):
UPDATE PERSON SET STATUS = ?, VERSION = ? WHERE ((ID = ?) AND (VERSION = ?))
bind => [Away, 2, 1, 1]
Step 3 does not generate any SQL, but it does not throw any exception, which I am expecting, as the 'username' is annotated as #Column(..., updatable = false). The print(...) method prints following output:
Merged (username change) : Person [id=1, version=2, username=UsErNaMe, status=Away]
This time the merge() operation has updated username, but not version. Also, now the database is out-of-sync with EntityManager cache.
Is this expected, or bug in EclipseLink?
UPDATE
Expected result is exception at Step 3 above.
UPDATE
Have filed bug here.
You marked the column as non-updatable, and EclipseLink detects that the only change made to the person you tell it to merge is the user name. But the user name must not be updated. So it doesn't issue any SQL update query.
If you mark a column as non-updatable, you shouldn't update it.
So, to make things clear, the behavior you observe is the expected behavior.
I have a query that I have been trying to turn into a CriteraQuery, but I don't get how to code the "IN" term of the query.
The JPA Query that works looks like this:
#NamedQuery(name = "User.fromSearchID",
query = "SELECT q FROM User q,"
+ " IN (q.data) AS s WHERE s.data LIKE :search"
+ " ORDER BY q.id")
And the entity that it works on looks like this:
#Entity
public class User {
#Id private Integer id;
#OneToMany private List<UserData> data;
... }
And the referenced entity is
#Entity
public class UserData {
#Id private Long id;
private String key;
private String data;
... }
The intended result (the NamedQuery works) is to pull out all User entities that have some match in their list of data attributes. For some reason the CriteraQuery syntax escapes my intuition. Any help?
I assume users should be unique?
Then JP QL version without rather old fashion IN is:
String searchArgument = "data1";
String query = " SELECT DISTINCT(u) " +
" FROM User u JOIN u.data ud " +
" WHERE ud.data LIKE :search ORDER BY u.id";
List<User> result =em.createQuery(query, User.class).
setParameter("search", searchArgument).getResultList();
And same via Criteria API:
String searchArgument = "data1";
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
Predicate dataLike = cb.like(user.join("data").<String>get("data"),
cb.parameter(String.class, "search"));
cq.distinct(true).select(user)
.where(dataLike)
.orderBy(cb.asc(user.get("id")));
TypedQuery<User> findUniqueUserByUserDataData = em.createQuery(cq);
findUniqueUserByUserDataData.setParameter("search", searchArgument);