I have an entity called packet, I want to update an attribute in all instances of that entity. The attribute I want to update is the price of the packet by a given percentage.
This is my entity class, it has both controller and service class:
@Entity
public class Packets {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private int id;
private String name;
private BigDecimal packetPrice;
...constructors, getters, setters...et
)
This is the class which I'm using for the @PutMapping:
@RestController
@RequestMapping(path = "changePrices")
public class ManipulatePrices {
@Autowired
PacketService packetService;
@PutMapping(path = "minus/{percentage}")
public void discount(@PathVariable("percentage") double percentage){
percentage = (100 - percentage)/100;
packetService.discount(percentage);
}
}
and this is the method in the PacketService class:
@Service
public class PacketService {
private final PacketRepository packetRepository;
public void discount(double percentage) {
for(int i=0; i < packetRepository.count(); i ) {
Packets packets = packetRepository.findAll().iterator().next();
BigDecimal finalPrice = packets.getPacketPrice().multiply(BigDecimal.valueOf(percentage));
packets.setPacketPrice(finalPrice);
packetRepository.save(packets);
}
}
so what's happening is that the change is being applied only to the first instance of the Packet entity (with id=1). How can I iterate through all the instances?
CodePudding user response:
You can add this method to your repository ,it'll modify all the entries of Packets table :
@Transactional
@Modifying
@Query(value=" UPDATE Packets p SET p.packetPrice = :percentage/100 ")
//p.packetPrice = :percentage/100 is just for the sake of the example
//keep in mind the :percentage is refering to the method parameter
void discount(@Param("percentage") double percentage);
Now you call this method in your modifying method of the RestController
@PutMapping(path = "minus/{percentage}")
public void discount(@PathVariable("percentage") double percentage){
percentage = (100 - percentage)/100;
packetRepository.discount(percentage);
}
CodePudding user response:
@Service
public class PacketService {
private final PacketRepository packetRepository;
public void discount(double percentage) {
List<Packets> packets = packetRepository.findAll();
List<Packets> newPackets = new ArrayList<>();
for(int i=0; i < packetRepository.size(); i ) {
Packets packet = packets.get(i);
BigDecimal finalPrice = packet.getPacketPrice().multiply(BigDecimal.valueOf(percentage));
packet.setPacketPrice(finalPrice);
newPackets.add(packet);
}
packetRepository.save(newPackets);
}
In this way, you get the list using findAll(); and then you iterate over that list. In newPackets variable you are storing your packets with new price. After the loop, you are storing the whole list in your db in a single query. This will help you with performance too.