About Question enthuware.oce-jpad.v6.2.439 :
Moderator: admin
Re: About Question enthuware.oce-jpad.v6.2.439 :
Without @MapKey the implicit is @MapKeyColumn and @MapKeyColumn is used if the key is NOT part of the value. @MapKeyClass is used in combination with @MapKeyColumn (because there is no possibility to derive the type as there is no field representing the key). If @MapKey is nor specified, then it is understood that the key is NOT part of the value. But in question assignment it is stated that cardNumber IS part of the value.
Therefore I still believe @MapKeyClass is invalid for the mapping in question assignment, as @MapKey MUST be used and this negates usage of @MapKeyClass.
Therefore I still believe @MapKeyClass is invalid for the mapping in question assignment, as @MapKey MUST be used and this negates usage of @MapKeyClass.
Re: About Question enthuware.oce-jpad.v6.2.439 :
If we don't specify the field to use as key in the map how can entity manager fill in the map for a given object reading from database (if we have more than one String attribure in related entity for example)?
Re: About Question enthuware.oce-jpad.v6.2.439 :
@OneToMany(targetEntity=CreditCard.class)
@MapKeyClass(String.class)
private Map creditCards;
so finally, this is correct or no?
@MapKeyClass(String.class)
private Map creditCards;
so finally, this is correct or no?
Re: About Question enthuware.oce-jpad.v6.2.439 :
@OneToMany(targetEntity=CreditCard.class)
@MapKeyClass(String.class)
private Map creditCards;
I think this is not correct. You have to specify somehow that column used as key is "cardNumber", and on this answer we don't have that.
@MapKeyClass(String.class)
private Map creditCards;
I think this is not correct. You have to specify somehow that column used as key is "cardNumber", and on this answer we don't have that.
-
- Site Admin
- Posts: 10036
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.oce-jpad.v6.2.439 :
The given answer is correct. There is no need to specify the field that is used as a key of the map because the persistent provider doesn't care about it. Consider the following code:
The point to understand here is that even though it is desirable to specify @MapKey(name="cardNumber"), it is not required.
Code: Select all
public Map<String, CreditCard> createCustomerCreditcardRelationships(String[] params){
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try
{
tx.begin();
Customer i = new Customer();
i.setName("John Doe");
CreditCard cc1 = new CreditCard();
cc1.setCardNumber("11111111111");
cc1.setCardType(CreditCardType.VISA);
CreditCard cc2 = new CreditCard();
cc2.setCardNumber("22222222222");
cc2.setCardType(CreditCardType.AMEX);
CreditCard cc3 = new CreditCard();
cc3.setCardNumber("33333333333");
cc3.setCardType(CreditCardType.MASTERCARD);
Map<String, CreditCard> ccList = new HashMap<String, CreditCard>();
ccList.put(cc1.getCardNumber(), cc1); //you can put any string as the key.
ccList.put(cc2.getCardNumber(), cc2);
ccList.put(cc3.getCardNumber(), cc3);
i.setCreditCards(ccList);
em.persist(i);
tx.commit();
System.out.println("Customer and CCs stored.");
return ccList;
}
finally
{
//tx should have been committed at this point,
//if it is not something went wrong. So rollback.
if (tx.isActive()) {
tx.rollback();
}
em.close();
}
}
public Map<String, CreditCard> testCustomerCreditcardRelationships(String[] params){
EntityManager em = emf.createEntityManager();
Integer custId = Integer.parseInt(params[0]);
try
{
Customer c = em.find(Customer.class, custId);
System.out.println(" Got customer "+c);
return c.getCreditCards(); //This will return the map and its keys will be whatever you stored earlier.
}
finally
{
em.close();
}
}
If you like our products and services, please help us by posting your review here.
-
- Site Admin
- Posts: 10036
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.oce-jpad.v6.2.439 :
The following is the code for Customer.java
Code: Select all
@Entity
public class Customer {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(cascade = {CascadeType.ALL }, fetch= FetchType.EAGER)
//@MapKey(name="cardNumber") //It works fine with and without this line
private Map<String, CreditCard> creditCards;
//getters and setters for ID, name, and creditCards.
}
If you like our products and services, please help us by posting your review here.
-
- Posts: 3
- Joined: Tue Jul 02, 2013 1:14 pm
- Contact:
Re: About Question enthuware.oce-jpad.v6.2.439 :
I agree with guys. Correctness of answer C is arguable. The question clearly stays that map key should be mapped to the same column that cardNumber field is. With answer C you will end up with two not related columns.
-
- Posts: 1
- Joined: Tue May 06, 2014 10:49 am
- Contact:
Re: About Question enthuware.oce-jpad.v6.2.439 :
I don't understand why (c) is correct. If you do not specify column name of map's key, how can entity manager know what value to load into map's key?
e.g.:
What are the key values of following "ccMap"?
Map<String, CreditCard> ccMap = em.load(1002, Customer.class).getCreditCards();
From one of previous post:
“There is no need to specify the field that is used as a key of the map because the persistent provider doesn't care about it.” and "//This will return the map and its keys will be whatever you stored earlier."--- They do not make sense.
What if
ccList.put(cc3.getCardNumber(), cc3);
is replaced by
ccList.put(cc3.getIssuer(), cc3);
?
As one of another previous post pointed out, (c) ends up with map's key being mapped to an extra column, not cardNumber column
e.g.:
Code: Select all
Customer_Table:
Customer_ID Customer_Name
1001 A
1002 B
Creditcard_Table:
CardID(int, PK) CardNamber(String) Issuer(String) Customer_ID (FK)
9001 1111222233334444 Citibank 1002
9002 5555666677778888 Amex 1002
Map<String, CreditCard> ccMap = em.load(1002, Customer.class).getCreditCards();
From one of previous post:
“There is no need to specify the field that is used as a key of the map because the persistent provider doesn't care about it.” and "//This will return the map and its keys will be whatever you stored earlier."--- They do not make sense.
What if
ccList.put(cc3.getCardNumber(), cc3);
is replaced by
ccList.put(cc3.getIssuer(), cc3);
?
As one of another previous post pointed out, (c) ends up with map's key being mapped to an extra column, not cardNumber column
-
- Site Admin
- Posts: 10036
- Joined: Fri Sep 10, 2010 9:26 pm
- Contact:
Re: About Question enthuware.oce-jpad.v6.2.439 :
You are missing the point. The persistent provider doesn't automatically associate cardnumber with the card. The code does it. Please see the lines in the code that I gave above:
You might want to try out the code given above.
HTH,
Paul.
Code: Select all
ccList.put(cc1.getCardNumber(), cc1); //you can put any string as the key.
ccList.put(cc2.getCardNumber(), cc2);
ccList.put(cc3.getCardNumber(), cc3);
i.setCreditCards(ccList);
That is not persistence provider's problem. The PP does not manage the semantics of the contents of your map. It only manages the storage of the map. If you store wrong data, you will get back wrong data.What if
ccList.put(cc3.getCardNumber(), cc3);
is replaced by
ccList.put(cc3.getIssuer(), cc3);
You might want to try out the code given above.
HTH,
Paul.
If you like our products and services, please help us by posting your review here.
Who is online
Users browsing this forum: No registered users and 24 guests