This question already has answers here:
How to access an object's parent object in Java?
(4 answers)
Closed 3 years ago.
I need to get the "host" object of another object. Here an example
Suppose I have the
class Peer {
final Service service;
public Peer(Service service) {
this.service = service;
}
public void ping() {
service.ping();
}
}
and
class Service {
public String hola() {
this.getPeer()? //HERE I NEED SOME COMMAND TO GET the Peer object, is this possible?
}
}
Then in Service class, I need to get the peer object. Is this possible?
You need to store the Peer object inside your Service object while creating an instance of Service, that's the only way for retrieving it.
Create inside Service a constructor which accepts Peer
class Service {
Peer peer;
public Service(Peer peer){
this.peer = peer;
}
public Peer getPeer() {
return peer;
}
public String hola() {
Peer peer = getPeer();
}
}
Thing is:
this.getPeer()? //HERE I NEED SOME COMMAND TO GET the Peer object, is this possible?
There is no "command" to do that. Simply spoken: java objects have no notion of the context they were created in. The only way for an instance of Service to know about the Peer that created it: for example by passing a reference to that Service object, for example within its constructor. Or by having a setter method on the Service class that allows you to do that.
But of course: that sounds like the wrong way. A service instance should be really independent of the Peers using it! In other words: if it really makes sense that a Service knows one (or multiple?!) peers, then the Service class needs a field to "remember" that relationship. But at least the example given here rather suggests that your Service should not at all know (or care) about the Peers using it!
Related
This question already has answers here:
Map a dto to an entity retrieved from database if Dto has Id using MapStruct
(2 answers)
Closed 2 years ago.
I'm creating some Spring app with REST Controller for communication with frontend
I have some complex objects containing reference to other objects. I want to make a Mockup class for those objects to send those mockups instead of real objects. Object -> Mockup conversion is easy, but I can't seem to find good solution for conversion of JSON objects into proper objects (I'm not receiving full data for the nested object, just some Id that let's me extract it from DB).
I think I need to #Autowire object I receive from REST POST, but I neither know if it's possible nor if it's good practice.
What's the proper solution for extracting nested dependancies for objects created from deserialized JSON?
Relevant code snippets:
public class Object {
NestedObject nestedObject;
...
}
//That's the part I'm not sure is proper solution
public class ObjectMockup {
#Autowired
private NestedObjectService nestedObjectService;
...
}
#PostMapping("/new-object")
public ObjectMockup postNewObject(#RequestBody ObjectMockup objectMockup) {
Object object = objectMockup.mockToObject();
...
return new ObjectMockup(object);
}
When I do it like that, NestedObjectService is not initialized and throws Exception as soon as I try to extract nested object from database, Probably because REST Controller did not Autowire Mockup's attribute.
Instead of having a method objectMockup.mockToObject() that fetches the data from the DB, you could:
Inject the service to the method
objectMockup.mockToObject(nestedObjectService)
Have a static factory method that takes the service and the mock:
NestedObject.mockToObject(objectMockup, nestedObjectService)
Have a separate MappingService:
#Service
public class MockToObjectMapperService {
#Autowired NestedObjectService nestedObjectService;
public Object mockToObject(objectMockup) {...}
}
// in Controller
Object object = mockToObjectMapperService.mockToObject(objectMockup);
Though your NestedObjectService could also contain this mapping method.
I'm kinda new on DDD and even after read the blue and red book I still have some questions about how to transform some principles to code, specifically using Kotlin and Java.
For example, I identify a Client aggregate root that receive some parameters need it for the creation like Name and Address:
class Client: AggregateRoot {
var clientId: ClienteId
var name: Name
var address: Address
constructor(name: Name,address: Address) : super(){
// validations ....
this.name = name
this.address = address
}
Easy part:
To create a new Client I receive a DTO inside the RS service and try to create a new Client class passing the parameters above, case everything was solid and all rules fulfilled I send the new instance of Client to the repository, pretty straight foward.
clientRepository.store(client)
Other part:
I need to search my Client to change the address so I send the id to the repository and find the Client inside the database then I need to convert the database entity to the aggregate root and return to the caller.
override fun getById(id: Long): Client {
val clientEntity = em.find(...)
val client: Client(.....) //But I need another constructor with ClientId
return client
}
Then I will need a new constructor one that receive more parameters like the ClientId
constructor(clientId: ClienteId,name: Name,address: Address) : super(){
The problem is that every service can call this new constructor and create a incorrect instance of my aggregation root, so my questions are:
Is there a way to hide the complete constructor just for the repository or specific layers to see. Like in C# when you could use internal.
Is there any solution for Java or Kotlin to not expose this constructor that should be used just on tests and integrations ?
Another example is if I didn't need the address to be passed every time a client is created but just after in another method like:
client.addAddress(address)
But in both cases I will need to fulfill the entire Client from the database so I will need a second constructor with the address parameter.
So, the problem is how to rehydrate an Aggregate from the persistence without breaking its encapsulation by exposing the wrong interface to the client code (i.e. the Application layer or the Presentation layer).
I see two solutions to this:
Use reflection to populate the fields. This is the solution that most ORMs use and it is also the most generic. It works for most persistence types, even when there is an impedance mismatch. Some ORMs need to annotate fields or relations.
Expose a different interface to the client code. This means that your Aggregate implementation is larger that the interface and contains additional initialization methods used only by the infrastructure.
As an example in pseudo-code your could have:
// what you want the upper layers to see
interface Client {
void addAddress(address);
}
// the actual implementations
public class ClientAggregate implements Client
{
void rehidrate(clientId,name,address){...}
void addAddress(address){...}
}
public class ClientRepository
{
// this method returns Client (interface)
Client getById(id){
val clientEntity = em.find(...)
val client = new ClientAggregate()
client.rehydrate(clientEntity.id, clientEntity.name, clientEntity.address)
return client //you are returning ClientAggregate but the other see only Client (interface)
}
}
As a side note, I don't expose the constructor to create an Aggregate from the Domain point of view. I like to have empty constructors and a dedicated method, named from the Ubiquitous language, that creates the Aggregate. The reason is that is not clear that the constructor creates a new Aggregate. The constructor instantiate a new instance of a class; it is more a implementation details than a domain concern. An example:
class Client {
constructor(){ //some internal initializations, if needed }
void register(name){ ... }
}
This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 9 years ago.
I am experienced in JavaScript but new to Java. I am trying to figure out how to pass a function as a parameter of another function. In JavaScript this would like the block in Figure 1.
Figure 1
function fetchData(url, callback) {
// Do ajax request and fetch data from possibly slow server
// When the request is done, call the callback function
callback(ajaxResponse);
}
Is there a similar way of doing this in Java? I have searched the internets, but found little that is helpful on a novice level.
Unfortunately, the only equivalent (that I know if) is defining an interface which your fetchData method will accept as a parameter, and instantiate an anonymous inner class using that interface. Or, the class calling the fetchData method can implement that interface itself and pass its own reference using this to method.
This is your method which accepts a "callback":
public void fetchData(String url, AjaxCompleteHandler callback){
// do stuff...
callback.handleAction(someData);
}
The definition of AjaxCompleteHandler
public interface AjaxCompleteHandler{
public void handleAction(String someData);
}
Anonymous inner class:
fetchData(targetUrl, new AjaxCompleteHandler(){
public void handleAction(String someData){
// do something with data
}
});
Or, if your class implements MyCoolInterface, you can simply call it like so:
fetchData(targetUrl, this);
I am struggling to apprehend the way client and server communicate in vaadin 7. I have understood it well when it comes to server->client communication, but I still I cannot grasp how it works the other way round, namely from client to server. I have read that on the client side one should not change the State, but they should send the relevant data through rpc. On the client side there is a MyComponentClientRpc inteface which contains some methods and the developer should implement them in the Connector class. Then one can instantiate the inteface as anonymous class on server and can call the method. However in case one has a String "myString" on client how can it be transfered to the server, since one can only call the method on server passing the parameters on the time of calling it? How can then one get the data lying on client?
public interface MyComponentClientRpc extends ClientRpc {
public void getString(String s);
}
public class MyComponentConnector extends AbstractComponentConnector {
#SuppressWarnings("serial")
MyComponentClientRpc mcRpc = new MyComponentClientRpc() {
public void getString(String s) {
// TODO Do something useful
????
}
};
public MyComponentConnector() {
registerRpc(MyComponentClientRpc.class, mcRpc);
String a = "myString";
....
}
In particular, how does one implement the method on client, how does one insert the data in it and how should it be called on the server?
However in case one has a String "myString" on client how can it be
transfered to the server, since one can only call the method on server
passing the parameters on the time of calling it? How can then one get
the data lying on client?
You are using the wrong mechanism. There are actually two RPCs, ClientRpc and ServerRpc. In your example, you use ClientRpc, which is for calls from the server to the client.
To communicate from the client to the server, you have to extend from ServerRpc.
In the client, you call
MyComponentClientRpc rpc = RpcProxy.create(MyComponentClientRpc.class, this)
in order to get the proxy.
I am using a Java Web Service for
#WebService()
public class myWebService {
/**
* Web service operation
*/
MyClass Obj ;
#WebMethod(operationName = "webmethod1")
#Oneway
public void webmethod1(#WebParam(name = "serailNo") String serailNo) {
obj = new MyClass();
//do some operations on obj;
}
/**
* Web service operation
*/
#WebMethod(operationName = "webmethod2")
public void webmethod2() {
//do some operations on obj after doing intial operations in web method1
}
}
I am unable to access obj in webmethod2. It is getting a null pointer exception.
As a detail : I want to create a object . That object should be accessed across all web methods. In such a way webmethod1 will do intial operations on obj and followed web method2 will use the same obj.
How can i achieve this
If you are creating a brand new object, what you could do, would be to make your webmethod1 return whatever object it creates, and then, make webmethod2 take that same object as a parameter.
Another option would be to make webmethod2 take in the serialNo parameter and check that the obj variable is not null. If it is, it will call webmethod1 by passing it that same serial number, and create the object so that it has something to work on.
The reason you are getting a nullpointer is because the webservice is not stateful, i.e the object does not exist during the second call. It is possible to create a stateful webservice but that depends on the kind of webservice and server your running it on...
As npinti mentioned you could send the object along with the service. Although that might not be favorable, e.g if the object is big.
You could create a local cache on the server containing all the created objects by and mapping them with the serialNo.