I got class:
public abstract class AbstractEntity {
#Getter
#Column(nullable = false, unique = true, updatable = false)
private UUID uuid = UUID.randomUUID();
}
and test:
def 'should be transitive: if x.equals(y) and y.equals(z) then x.equals(z)'() {
given:
AbstractEntity place = new Place()
AbstractEntity secondPlace = new Place()
AbstractEntity thirdPlace = new Place()
and: 'all entities has same uuid what makes them equal'
secondPlace.changeUuid(place.uuid)
thirdPlace.changeUuid(place.uuid)
line secondPlace.changeUuid(place.uuid) throws exception: groovy.lang.ReadOnlyPropertyException: Cannot set readonly property
How can I set this field value without using java reflection?
You seem to have an attribute in the #Column 'updatable = false. My first reaction is to think that this stops variables from being updated.
There is also no #Setter annotation which could be useful in this scenario.
Then you could use this method within your test.
Related
I've been struggling with trying to figure out the problem and fixing the error when I tried to pass HashMap into a constructor. My scenario is:
I've a Student class:
public class Student {
String name;
String major;
String level;
public Student (String name, String major, String level) {
this.name = name;
this.major = major;
this.level = level;
}
}
I've another class, called TA_Manager that is a subclass of Student. This TA_Manager class uses HashMap to collect the students (who are TA) from the Student class:
import java.util.HashMap;
public class TA_Manager extends Student {
HashMap<String, Student> TA;
public TA_Manager(HashMap<String, Student> TA) {
this.TA = TA;
}
}
In the main class, I've created three student objects and I put two of the students into the HashMap (they are TAs). Then I create a TA_Manager object and pass the HashMap into the TA_Manager class:
import java.util.HashMap;
public class Test {
public static void main(String[] args) {
Student s1 = new Student("A", "CS", "Junior");
Student s2 = new Student("B", "IS", "Senior");
Student s3 = new Student("C", "CE", "Senior");
HashMap<String, Student> TA = new HashMap<String, Student>();
TA.put("TA1", s1);
TA.put("TA2", s2);
TA_Manager tamgr = new TA_Manager (TA);
}
}
When I run the main class, it returns error:
TA_Manager.java:6: error: constructor Student in class Student cannot be applied to given types;
public TA_Manager(HashMap<String, Student> TA) {
^
required: String,String,String
found: no arguments
I actually have searched this HashMap problem and I followed the solution given on how to pass the HashMap into the constructor:
Pass a HashMap as parameter in Java
and also from this link on how to pass a class as hashmap value:
Can HashMap contain custom class for key/value?
But I still get the error message. I don't know how to fix this error. Can anyone bring some light into this. Really appreciated.
The error is caused because java is trying to call the no-arg constructor of your Student class, but you only have a three argument public constructor.
The simplest solution is to create an empty public constructor for your student.
public Student(){
//do nothing and leave values as null.
}
This is not a very practical solution. The problem is a bit conceptual. Your TA class is a Student, but you don't give it a name major or level.
The next way to manage this would be to call the current constructor with some values.
public TA_Manager(HashMap<String, Student> TA) {
super( null, null, null);
this.TA = TA;
}
Now java knows to use the public constructor instead of the no-arg one. I left the values as null because I don't know what default values you would have. This is practical when there are useful default values that you wouldn't need to include during construction.
Personally, I would expect the TA to be a full student AND have a hashmap.
public TA_Manager (String name, String major, String level) {
super(name, major, level);
this.TA = new HashMap<>();
}
In this case you would create the manager, then add all of the students afterwards. It has the advantage that your TA_Manager is a fully formed student though.
I have the below JSON code that needs to be parsed. I'm using the corresponding JAX-RS models. The problem is that the paymillClient object is null. If I add currency as a string inside the PaymillSubscription object, it returns EUR value, not null. So there appears to be a problem with the PaymillClient object, not plain strings. Could there be a limit to the number of nested objects for parsing ? Ex, max 2 nested objects. So because there are 3 in my case, it doesn't work.
Unfortunately, I cannot change the JSON code that needs to be parsed at all. I just need to make it work with the JAX-RS implementation.
{
"event":{
"event_type":"subscription.succeeded",
"event_resource":{
"subscription":{
"id":"sub_29f144a3bc32c71f96e2",
"offer":{ },
"livemode":false,
"amount":200,
"temp_amount":null,
"currency":"EUR",
"name":"Monthly subscription",
"interval":"1 MONTH",
"trial_start":null,
"trial_end":null,
"period_of_validity":null,
"end_of_period":null,
"next_capture_at":1428939744,
"created_at":1426264944,
"updated_at":1426264944,
"canceled_at":null,
"payment":{ },
"app_id":null,
"is_canceled":false,
"is_deleted":false,
"status":"active",
"client":{
"id":"client_c0c24aa7f97e1b8ed15d"
}
},
"transaction":{ }
},
"created_at":1426264944,
"app_id":null
}
}
PaymillEventContainer:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventContainer
{
private PaymillEvent event;
}
PaymillEvent:
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEvent
{
#XmlElement(name = "event_type") #DocumentationExample(value = "subscription.succeeded") private String eventType;
#XmlElement(name = "event_resource") private PaymillEventResource eventResource;
}
PaymillEventResource:
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymillEventResource
{
private PaymillClient client;
private PaymillOffer offer;
private PaymillSubscription subscription;
}
PaymillSubscription:
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymillSubscription
{
private PaymillClient client;
private PaymillOffer offer;
}
PaymillClient:
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymillClient
{
#DocumentationExample(value = "client_c0c24aa7f97e1b8ed15d") private String id;
}
API endpoint code:
public Response postSubscriptionSucceeded(PaymillEventContainer paymillEventContainer)
{
PaymillEvent paymillEvent = paymillEventContainer.getPaymillEvent();
PaymillEventResource paymillEventResource = paymillEvent.getEventResource();
PaymillSubscription paymillSubscription = paymillEventResource.getSubscription();
PaymillClient paymillClient = paymillSubscription.getPaymillClient();
PaymillOffer paymillOffer = paymillSubscription.getPaymillOffer();
String clientId = paymillClient.getId(); // NullPointerException
}
Ok. I tried to run your code on your machine and also received null (note, that I'm using MOXy to unmarshall JSON). Then, I tried to experiment with it a little and found really funny things:
1. If you will remove all null-valued fields from your JSON, all works just perfect.
2. If you will add another field to PaymillSubscription. I added private Test test, where Test is:
#XmlAccessorType(XmlAccessType.FIELD)
public class Test {
private String id;
}
And will send this "test" object between last null-valued field in subscription object and "client" field:
"test":{"id":"sadas"},
"client":{
"id":"client_c0c24aa7f97e1b8ed15d"
}
Then "test" would be null, but "client" will be parsed as expected.
3. If you will add all null-valued objects into model (I mean, create respective fields in PaymillSubscription class) all works just perfect.
It seems, that by default JAXB specification doesn't allow JSON with unrecognized fields, but MOXy still tries to parse it (and sometimes produces errors).
I have a Groovy class and want to make sure that certain attributes are always set in the constructor.
Is there any way to way to make attributes mandatory in a Groovy class?
Thanks
You could use #TupleConstructor with specific attribute force :
import groovy.transform.TupleConstructor
#TupleConstructor(force=true)
class Car {
String brand
List options
private boolean sold = false
// constructor
Car(boolean sold) {
this.sold = sold
}
boolean hasBeenSold() { sold }
}
}
car = new Car(true)
assert car.hasBeenSold
More info
I have a class that has 2 properties and a constructor:
public class Card
{
public int CardName {get;set;}
public bool IsActive {get;set;}
public Card (int cardName, bool isActive)
{
CardName = cardName;
IsActive = isActive;
}
}
How do I force the developer to use the constructor instead of doing the following:
var card = new Card{ CardName = "blab", IsActive = true };
On a side note, what is the statement above called? Is that a lazy loading statement?
You already have.
By not having an empty constructor you've removed the ability to use the object initializer method of creating an object.
This:
var card = new Card{ CardName = "blab", IsActive = true };
is the same as this
var card = new Card() { CardName = "blab", IsActive = true };
And in this context new Card() is not valid.
That depends on why you want to prevent the syntax in question.
The object initializer syntax is shorthand for setting a bunch of properties immediately after construction. That is, this:
var c = new Card { CardName = "foo", IsActive = true };
Is semantically identical to this:
var c = new Card();
c.CardName = "foo";
c.IsActive = true;
In both cases, a constructor does run, but its immediately followed by a series of property initializers to apply to the new object.
In your case, since there is no parameterless constructor, you cannot use the object initializer syntax the way you posted. However, it is legal to pass constructor parameters along with the object initializer, so the following would be legal for your class:
var c = new Card("", false) { CardName = "foo", IsActive = true };
(One could argue that this syntax makes the meaning of values more clear than simply passing them to a constructor; one could also argue its just being excessively stubborn :) I could go either way)
You could prevent this second syntax from working by removing the public setters for those properties. If your goal is to prevent the user from changing the values passed into the constructor, making an immutable Card object, for example, that would be the way to go.
I should point out, though, that if one of my juniors asked me this question at work I'd really want to know why they found it necessary to prevent object initialization from being used. There are valid reasons, of course, but they are usually not the source of the question. Object initializers are a good thing -- there are cases where this syntax is very convenient (particularly with LINQ) and I use it all the time.
If you do some kind of setup in the constructor based on the initial values, but those properties are public-settable, you already have to deal with a case where the user changes those values after construction. If your goal is merely to ensure that some "setup" code happens when the object is first constructed, put that code into a default constructor and chain them together:
public class Card
{
public string CardName { get; set; }
public bool IsActive { get; set; }
public Card()
{
// setup code here.
}
public Card ( string name, bool active )
: this()
{
this.CardName = name;
this.IsActive = active;
}
}
Declare the getters of the property as 'Private'.
Something like Public int CardName {private get; set;}.
I have the following java class and have placed an XmlJavaAdapter annotation on the payerPartyReference variable. I want the adapter PartyReferenceAdapter to be used for unmarshalling ONLY this variable, not any other variables which have the same type of PartyReference, whether in this class or some other class. How can I do this? Thanks for your help!
public class InitialPayment extends PaymentBase
{
// Want PartyReferenceAdapter to be used here
#XmlJavaTypeAdapter(PartyReferenceAdapter.class)
protected PartyReference payerPartyReference;
//
// Dont want PartyReferenceAdapter to be used here
protected PartyReference receiverPartyReference;
//
protected AccountReference receiverAccountReference;
#XmlSchemaType(name = "date")
protected XMLGregorianCalendar adjustablePaymentDate;
#XmlSchemaType(name = "date")
protected XMLGregorianCalendar adjustedPaymentDate;
protected Money paymentAmount;
}
My Adapter is defined as follows:
public class PartyReferenceAdapter
extends XmlAdapter < Object, PartyReference > {
public PartyReference unmarshal(Object obj) throws Exception {
Element element = null;
if (obj instanceof Element) {
element = (Element)obj;
String reference_id = element.getAttribute("href");
PartyReference pr = new PartyReference();
pr.setHref(reference_id);
return pr;
}
public Object marshal(PartyReference arg0) throws Exception {
return null;
}
}
Field/Property Level
If you set #XmlJavaTypeAdapter on a field/property it will only be used for that property.
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
Type Level
If you set #XmlJavaTypeAdapter on a type, then it will used for all references to that type.
http://bdoughan.blogspot.com/2010/12/jaxb-and-immutable-objects.html
Package Level
If you set #XmlJavaTypeAdapter on a package, then it will be used for all references to that type within that package:
http://bdoughan.blogspot.com/2011/05/jaxb-and-joda-time-dates-and-times.html